VirtualBox

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

Last change on this file since 22875 was 13837, checked in by vboxsync, 16 years ago

s/%Vr\([acfs]\)/%Rr\1/g - since I'm upsetting everyone anyway, better make the most of it...

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.0 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 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22
23#define LOG_GROUP_MAIN_OVERRIDE LOG_GROUP_HGCM
24#include "Logging.h"
25
26#include "hgcm/HGCMObjects.h"
27
28#include <string.h>
29
30#include <VBox/err.h>
31
32
33static RTCRITSECT g_critsect;
34
35/* There are internal handles, which are not saved,
36 * and client handles, which are saved.
37 * They use different range of values:
38 * 1..7FFFFFFF for clients,
39 * 0x80000001..0xFFFFFFFF for other handles.
40 */
41static uint32_t volatile g_u32InternalHandleCount;
42static uint32_t volatile g_u32ClientHandleCount;
43
44static PAVLULNODECORE g_pTree;
45
46
47DECLINLINE(int) hgcmObjEnter (void)
48{
49 return RTCritSectEnter (&g_critsect);
50}
51
52DECLINLINE(void) hgcmObjLeave (void)
53{
54 RTCritSectLeave (&g_critsect);
55}
56
57int hgcmObjInit (void)
58{
59 int rc = VINF_SUCCESS;
60
61 LogFlow(("MAIN::hgcmObjInit\n"));
62
63 g_u32InternalHandleCount = 0x80000000;
64 g_u32ClientHandleCount = 0;
65 g_pTree = NULL;
66
67 rc = RTCritSectInit (&g_critsect);
68
69 LogFlow(("MAIN::hgcmObjInit: rc = %Rrc\n", rc));
70
71 return rc;
72}
73
74void hgcmObjUninit (void)
75{
76 if (RTCritSectIsInitialized (&g_critsect))
77 {
78 RTCritSectDelete (&g_critsect);
79 }
80}
81
82uint32_t hgcmObjMake (HGCMObject *pObject, uint32_t u32HandleIn)
83{
84 int handle = 0;
85
86 LogFlow(("MAIN::hgcmObjGenerateHandle: pObject %p\n", pObject));
87
88 int rc = hgcmObjEnter ();
89
90 if (RT_SUCCESS(rc))
91 {
92 ObjectAVLCore *pCore = &pObject->Core;
93
94 /* Generate a new handle value. */
95
96 uint32_t volatile *pu32HandleCountSource = pObject->Type () == HGCMOBJ_CLIENT?
97 &g_u32ClientHandleCount:
98 &g_u32InternalHandleCount;
99
100 uint32_t u32Start = *pu32HandleCountSource;
101
102 for (;;)
103 {
104 uint32_t Key;
105
106 if (u32HandleIn == 0)
107 {
108 Key = ASMAtomicIncU32 (pu32HandleCountSource);
109
110 if (Key == u32Start)
111 {
112 /* Rollover. Something is wrong. */
113 AssertReleaseFailed ();
114 break;
115 }
116
117 /* 0 and 0x80000000 are not valid handles. */
118 if ((Key & 0x7FFFFFFF) == 0)
119 {
120 /* Over the invalid value, reinitialize the source. */
121 *pu32HandleCountSource = pObject->Type () == HGCMOBJ_CLIENT?
122 0:
123 0x80000000;
124 continue;
125 }
126 }
127 else
128 {
129 Key = u32HandleIn;
130 }
131
132 /* Insert object to AVL tree. */
133 pCore->AvlCore.Key = Key;
134
135 bool bRC = RTAvlULInsert(&g_pTree, &pCore->AvlCore);
136
137 /* Could not insert a handle. */
138 if (!bRC)
139 {
140 if (u32HandleIn == 0)
141 {
142 /* Try another generated handle. */
143 continue;
144 }
145 else
146 {
147 /* Could not use the specified handle. */
148 break;
149 }
150 }
151
152 /* Initialize backlink. */
153 pCore->pSelf = pObject;
154
155 /* Reference the object for time while it resides in the tree. */
156 pObject->Reference ();
157
158 /* Store returned handle. */
159 handle = Key;
160
161 Log(("Object key inserted 0x%08X\n", Key));
162
163 break;
164 }
165
166 hgcmObjLeave ();
167 }
168 else
169 {
170 AssertReleaseMsgFailed (("MAIN::hgcmObjGenerateHandle: Failed to acquire object pool semaphore"));
171 }
172
173 LogFlow(("MAIN::hgcmObjGenerateHandle: handle = 0x%08X, rc = %Rrc, return void\n", handle, rc));
174
175 return handle;
176}
177
178uint32_t hgcmObjGenerateHandle (HGCMObject *pObject)
179{
180 return hgcmObjMake (pObject, 0);
181}
182
183uint32_t hgcmObjAssignHandle (HGCMObject *pObject, uint32_t u32Handle)
184{
185 return hgcmObjMake (pObject, u32Handle);
186}
187
188void hgcmObjDeleteHandle (uint32_t handle)
189{
190 int rc = VINF_SUCCESS;
191
192 LogFlow(("MAIN::hgcmObjDeleteHandle: handle 0x%08X\n", handle));
193
194 if (handle)
195 {
196 rc = hgcmObjEnter ();
197
198 if (RT_SUCCESS(rc))
199 {
200 ObjectAVLCore *pCore = (ObjectAVLCore *)RTAvlULRemove (&g_pTree, handle);
201
202 if (pCore)
203 {
204 AssertRelease(pCore->pSelf);
205
206 pCore->pSelf->Dereference ();
207 }
208
209 hgcmObjLeave ();
210 }
211 else
212 {
213 AssertReleaseMsgFailed (("Failed to acquire object pool semaphore, rc = %Rrc", rc));
214 }
215 }
216
217 LogFlow(("MAIN::hgcmObjDeleteHandle: rc = %Rrc, return void\n", rc));
218
219 return;
220}
221
222HGCMObject *hgcmObjReference (uint32_t handle, HGCMOBJ_TYPE enmObjType)
223{
224 LogFlow(("MAIN::hgcmObjReference: handle 0x%08X\n", handle));
225
226 HGCMObject *pObject = NULL;
227
228 if ((handle & 0x7FFFFFFF) == 0)
229 {
230 return pObject;
231 }
232
233 int rc = hgcmObjEnter ();
234
235 if (RT_SUCCESS(rc))
236 {
237 ObjectAVLCore *pCore = (ObjectAVLCore *)RTAvlULGet (&g_pTree, handle);
238
239 Assert(!pCore || (pCore->pSelf && pCore->pSelf->Type() == enmObjType));
240 if ( pCore
241 && pCore->pSelf
242 && pCore->pSelf->Type() == enmObjType)
243 {
244 pObject = pCore->pSelf;
245
246 AssertRelease(pObject);
247
248 pObject->Reference ();
249 }
250
251 hgcmObjLeave ();
252 }
253 else
254 {
255 AssertReleaseMsgFailed (("Failed to acquire object pool semaphore, rc = %Rrc", rc));
256 }
257
258 LogFlow(("MAIN::hgcmObjReference: return pObject %p\n", pObject));
259
260 return pObject;
261}
262
263void hgcmObjDereference (HGCMObject *pObject)
264{
265 LogFlow(("MAIN::hgcmObjDereference: pObject %p\n", pObject));
266
267 AssertRelease(pObject);
268
269 pObject->Dereference ();
270
271 LogFlow(("MAIN::hgcmObjDereference: return\n"));
272}
273
274uint32_t hgcmObjQueryHandleCount ()
275{
276 return g_u32ClientHandleCount;
277}
278
279void hgcmObjSetHandleCount (uint32_t u32ClientHandleCount)
280{
281 Assert(g_u32ClientHandleCount <= u32ClientHandleCount);
282
283 int rc = hgcmObjEnter ();
284
285 if (RT_SUCCESS(rc))
286 {
287 if (g_u32ClientHandleCount <= u32ClientHandleCount)
288 g_u32ClientHandleCount = u32ClientHandleCount;
289 hgcmObjLeave ();
290 }
291}
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