VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/HGCMObjects.cpp@ 94521

Last change on this file since 94521 was 93115, checked in by vboxsync, 2 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1/* $Id: HGCMObjects.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * HGCMObjects - Host-Guest Communication Manager objects
4 */
5
6/*
7 * Copyright (C) 2006-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#define LOG_GROUP LOG_GROUP_HGCM
19#include "LoggingNew.h"
20
21#include "HGCMObjects.h"
22
23#include <iprt/string.h>
24#include <iprt/errcore.h>
25
26
27static RTCRITSECT g_critsect;
28
29/* There are internal handles, which are not saved,
30 * and client handles, which are saved.
31 * They use different range of values:
32 * 1..7FFFFFFF for clients,
33 * 0x80000001..0xFFFFFFFF for other handles.
34 */
35static uint32_t volatile g_u32InternalHandleCount;
36static uint32_t volatile g_u32ClientHandleCount;
37
38static PAVLU32NODECORE g_pTree;
39
40
41DECLINLINE(int) hgcmObjEnter(void)
42{
43 return RTCritSectEnter(&g_critsect);
44}
45
46DECLINLINE(void) hgcmObjLeave(void)
47{
48 RTCritSectLeave(&g_critsect);
49}
50
51int hgcmObjInit(void)
52{
53 LogFlow(("MAIN::hgcmObjInit\n"));
54
55 g_u32InternalHandleCount = 0x80000000;
56 g_u32ClientHandleCount = 0;
57 g_pTree = NULL;
58
59 int rc = RTCritSectInit(&g_critsect);
60
61 LogFlow(("MAIN::hgcmObjInit: rc = %Rrc\n", rc));
62
63 return rc;
64}
65
66void hgcmObjUninit(void)
67{
68 if (RTCritSectIsInitialized(&g_critsect))
69 RTCritSectDelete(&g_critsect);
70}
71
72uint32_t hgcmObjMake(HGCMObject *pObject, uint32_t u32HandleIn)
73{
74 int handle = 0;
75
76 LogFlow(("MAIN::hgcmObjGenerateHandle: pObject %p\n", pObject));
77
78 int rc = hgcmObjEnter();
79
80 if (RT_SUCCESS(rc))
81 {
82 ObjectAVLCore *pCore = &pObject->m_core;
83
84 /* Generate a new handle value. */
85
86 uint32_t volatile *pu32HandleCountSource = pObject->Type () == HGCMOBJ_CLIENT?
87 &g_u32ClientHandleCount:
88 &g_u32InternalHandleCount;
89
90 uint32_t u32Start = *pu32HandleCountSource;
91
92 for (;;)
93 {
94 uint32_t Key;
95
96 if (u32HandleIn == 0)
97 {
98 Key = ASMAtomicIncU32(pu32HandleCountSource);
99
100 if (Key == u32Start)
101 {
102 /* Rollover. Something is wrong. */
103 AssertReleaseFailed();
104 break;
105 }
106
107 /* 0 and 0x80000000 are not valid handles. */
108 if ((Key & 0x7FFFFFFF) == 0)
109 {
110 /* Over the invalid value, reinitialize the source. */
111 *pu32HandleCountSource = pObject->Type () == HGCMOBJ_CLIENT?
112 0:
113 UINT32_C(0x80000000);
114 continue;
115 }
116 }
117 else
118 {
119 Key = u32HandleIn;
120 }
121
122 /* Insert object to AVL tree. */
123 pCore->AvlCore.Key = Key;
124
125 bool fRC = RTAvlU32Insert(&g_pTree, &pCore->AvlCore);
126
127 /* Could not insert a handle. */
128 if (!fRC)
129 {
130 if (u32HandleIn == 0)
131 {
132 /* Try another generated handle. */
133 continue;
134 }
135 /* Could not use the specified handle. */
136 break;
137 }
138
139 /* Initialize backlink. */
140 pCore->pSelf = pObject;
141
142 /* Reference the object for time while it resides in the tree. */
143 pObject->Reference();
144
145 /* Store returned handle. */
146 handle = Key;
147
148 Log(("Object key inserted 0x%08X\n", Key));
149
150 break;
151 }
152
153 hgcmObjLeave();
154 }
155 else
156 {
157 AssertReleaseMsgFailed(("MAIN::hgcmObjGenerateHandle: Failed to acquire object pool semaphore"));
158 }
159
160 LogFlow(("MAIN::hgcmObjGenerateHandle: handle = 0x%08X, rc = %Rrc, return void\n", handle, rc));
161
162 return handle;
163}
164
165uint32_t hgcmObjGenerateHandle(HGCMObject *pObject)
166{
167 return hgcmObjMake(pObject, 0);
168}
169
170uint32_t hgcmObjAssignHandle(HGCMObject *pObject, uint32_t u32Handle)
171{
172 return hgcmObjMake(pObject, u32Handle);
173}
174
175void hgcmObjDeleteHandle(uint32_t handle)
176{
177 int rc = VINF_SUCCESS;
178
179 LogFlow(("MAIN::hgcmObjDeleteHandle: handle 0x%08X\n", handle));
180
181 if (handle)
182 {
183 rc = hgcmObjEnter();
184
185 if (RT_SUCCESS(rc))
186 {
187 ObjectAVLCore *pCore = (ObjectAVLCore *)RTAvlU32Remove(&g_pTree, handle);
188
189 if (pCore)
190 {
191 AssertRelease(pCore->pSelf);
192
193 pCore->pSelf->Dereference();
194 }
195
196 hgcmObjLeave();
197 }
198 else
199 {
200 AssertReleaseMsgFailed(("Failed to acquire object pool semaphore, rc = %Rrc", rc));
201 }
202 }
203
204 LogFlow(("MAIN::hgcmObjDeleteHandle: rc = %Rrc, return void\n", rc));
205}
206
207HGCMObject *hgcmObjReference (uint32_t handle, HGCMOBJ_TYPE enmObjType)
208{
209 LogFlow(("MAIN::hgcmObjReference: handle 0x%08X\n", handle));
210
211 HGCMObject *pObject = NULL;
212
213 if ((handle & UINT32_C(0x7FFFFFFF)) == 0)
214 {
215 return pObject;
216 }
217
218 int rc = hgcmObjEnter();
219
220 if (RT_SUCCESS(rc))
221 {
222 ObjectAVLCore *pCore = (ObjectAVLCore *)RTAvlU32Get(&g_pTree, handle);
223
224 Assert(!pCore || (pCore->pSelf && pCore->pSelf->Type() == enmObjType));
225 if ( pCore
226 && pCore->pSelf
227 && pCore->pSelf->Type() == enmObjType)
228 {
229 pObject = pCore->pSelf;
230
231 AssertRelease(pObject);
232
233 pObject->Reference();
234 }
235
236 hgcmObjLeave();
237 }
238 else
239 {
240 AssertReleaseMsgFailed(("Failed to acquire object pool semaphore, rc = %Rrc", rc));
241 }
242
243 LogFlow(("MAIN::hgcmObjReference: return pObject %p\n", pObject));
244
245 return pObject;
246}
247
248void hgcmObjDereference(HGCMObject *pObject)
249{
250 LogFlow(("MAIN::hgcmObjDereference: pObject %p\n", pObject));
251
252 AssertRelease(pObject);
253
254 pObject->Dereference();
255
256 LogFlow(("MAIN::hgcmObjDereference: return\n"));
257}
258
259uint32_t hgcmObjQueryHandleCount()
260{
261 return g_u32ClientHandleCount;
262}
263
264void hgcmObjSetHandleCount(uint32_t u32ClientHandleCount)
265{
266 Assert(g_u32ClientHandleCount <= u32ClientHandleCount);
267
268 int rc = hgcmObjEnter();
269
270 if (RT_SUCCESS(rc))
271 {
272 if (g_u32ClientHandleCount <= u32ClientHandleCount)
273 g_u32ClientHandleCount = u32ClientHandleCount;
274 hgcmObjLeave();
275 }
276}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use