VirtualBox

source: vbox/trunk/src/VBox/Main/hgcm/HGCMObjects.cpp@ 6828

Last change on this file since 6828 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette