VirtualBox

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

Last change on this file since 39411 was 35374, checked in by vboxsync, 14 years ago

hgcm -> main

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.8 KB
Line 
1/* $Id: HGCMObjects.cpp 35374 2010-12-30 14:42:15Z vboxsync $ */
2/** @file
3 * HGCMObjects - Host-Guest Communication Manager objects
4 */
5
6/*
7 * Copyright (C) 2006-2010 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_MAIN_OVERRIDE LOG_GROUP_HGCM
19#include "Logging.h"
20
21#include "HGCMObjects.h"
22
23#include <iprt/string.h>
24#include <VBox/err.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 PAVLULNODECORE 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 int rc = VINF_SUCCESS;
54
55 LogFlow(("MAIN::hgcmObjInit\n"));
56
57 g_u32InternalHandleCount = 0x80000000;
58 g_u32ClientHandleCount = 0;
59 g_pTree = NULL;
60
61 rc = RTCritSectInit (&g_critsect);
62
63 LogFlow(("MAIN::hgcmObjInit: rc = %Rrc\n", rc));
64
65 return rc;
66}
67
68void hgcmObjUninit (void)
69{
70 if (RTCritSectIsInitialized (&g_critsect))
71 {
72 RTCritSectDelete (&g_critsect);
73 }
74}
75
76uint32_t hgcmObjMake (HGCMObject *pObject, uint32_t u32HandleIn)
77{
78 int handle = 0;
79
80 LogFlow(("MAIN::hgcmObjGenerateHandle: pObject %p\n", pObject));
81
82 int rc = hgcmObjEnter ();
83
84 if (RT_SUCCESS(rc))
85 {
86 ObjectAVLCore *pCore = &pObject->m_core;
87
88 /* Generate a new handle value. */
89
90 uint32_t volatile *pu32HandleCountSource = pObject->Type () == HGCMOBJ_CLIENT?
91 &g_u32ClientHandleCount:
92 &g_u32InternalHandleCount;
93
94 uint32_t u32Start = *pu32HandleCountSource;
95
96 for (;;)
97 {
98 uint32_t Key;
99
100 if (u32HandleIn == 0)
101 {
102 Key = ASMAtomicIncU32 (pu32HandleCountSource);
103
104 if (Key == u32Start)
105 {
106 /* Rollover. Something is wrong. */
107 AssertReleaseFailed ();
108 break;
109 }
110
111 /* 0 and 0x80000000 are not valid handles. */
112 if ((Key & 0x7FFFFFFF) == 0)
113 {
114 /* Over the invalid value, reinitialize the source. */
115 *pu32HandleCountSource = pObject->Type () == HGCMOBJ_CLIENT?
116 0:
117 0x80000000;
118 continue;
119 }
120 }
121 else
122 {
123 Key = u32HandleIn;
124 }
125
126 /* Insert object to AVL tree. */
127 pCore->AvlCore.Key = Key;
128
129 bool bRC = RTAvlULInsert(&g_pTree, &pCore->AvlCore);
130
131 /* Could not insert a handle. */
132 if (!bRC)
133 {
134 if (u32HandleIn == 0)
135 {
136 /* Try another generated handle. */
137 continue;
138 }
139 else
140 {
141 /* Could not use the specified handle. */
142 break;
143 }
144 }
145
146 /* Initialize backlink. */
147 pCore->pSelf = pObject;
148
149 /* Reference the object for time while it resides in the tree. */
150 pObject->Reference ();
151
152 /* Store returned handle. */
153 handle = Key;
154
155 Log(("Object key inserted 0x%08X\n", Key));
156
157 break;
158 }
159
160 hgcmObjLeave ();
161 }
162 else
163 {
164 AssertReleaseMsgFailed (("MAIN::hgcmObjGenerateHandle: Failed to acquire object pool semaphore"));
165 }
166
167 LogFlow(("MAIN::hgcmObjGenerateHandle: handle = 0x%08X, rc = %Rrc, return void\n", handle, rc));
168
169 return handle;
170}
171
172uint32_t hgcmObjGenerateHandle (HGCMObject *pObject)
173{
174 return hgcmObjMake (pObject, 0);
175}
176
177uint32_t hgcmObjAssignHandle (HGCMObject *pObject, uint32_t u32Handle)
178{
179 return hgcmObjMake (pObject, u32Handle);
180}
181
182void hgcmObjDeleteHandle (uint32_t handle)
183{
184 int rc = VINF_SUCCESS;
185
186 LogFlow(("MAIN::hgcmObjDeleteHandle: handle 0x%08X\n", handle));
187
188 if (handle)
189 {
190 rc = hgcmObjEnter ();
191
192 if (RT_SUCCESS(rc))
193 {
194 ObjectAVLCore *pCore = (ObjectAVLCore *)RTAvlULRemove (&g_pTree, handle);
195
196 if (pCore)
197 {
198 AssertRelease(pCore->pSelf);
199
200 pCore->pSelf->Dereference ();
201 }
202
203 hgcmObjLeave ();
204 }
205 else
206 {
207 AssertReleaseMsgFailed (("Failed to acquire object pool semaphore, rc = %Rrc", rc));
208 }
209 }
210
211 LogFlow(("MAIN::hgcmObjDeleteHandle: rc = %Rrc, return void\n", rc));
212
213 return;
214}
215
216HGCMObject *hgcmObjReference (uint32_t handle, HGCMOBJ_TYPE enmObjType)
217{
218 LogFlow(("MAIN::hgcmObjReference: handle 0x%08X\n", handle));
219
220 HGCMObject *pObject = NULL;
221
222 if ((handle & 0x7FFFFFFF) == 0)
223 {
224 return pObject;
225 }
226
227 int rc = hgcmObjEnter ();
228
229 if (RT_SUCCESS(rc))
230 {
231 ObjectAVLCore *pCore = (ObjectAVLCore *)RTAvlULGet (&g_pTree, handle);
232
233 Assert(!pCore || (pCore->pSelf && pCore->pSelf->Type() == enmObjType));
234 if ( pCore
235 && pCore->pSelf
236 && pCore->pSelf->Type() == enmObjType)
237 {
238 pObject = pCore->pSelf;
239
240 AssertRelease(pObject);
241
242 pObject->Reference ();
243 }
244
245 hgcmObjLeave ();
246 }
247 else
248 {
249 AssertReleaseMsgFailed (("Failed to acquire object pool semaphore, rc = %Rrc", rc));
250 }
251
252 LogFlow(("MAIN::hgcmObjReference: return pObject %p\n", pObject));
253
254 return pObject;
255}
256
257void hgcmObjDereference (HGCMObject *pObject)
258{
259 LogFlow(("MAIN::hgcmObjDereference: pObject %p\n", pObject));
260
261 AssertRelease(pObject);
262
263 pObject->Dereference ();
264
265 LogFlow(("MAIN::hgcmObjDereference: return\n"));
266}
267
268uint32_t hgcmObjQueryHandleCount ()
269{
270 return g_u32ClientHandleCount;
271}
272
273void hgcmObjSetHandleCount (uint32_t u32ClientHandleCount)
274{
275 Assert(g_u32ClientHandleCount <= u32ClientHandleCount);
276
277 int rc = hgcmObjEnter ();
278
279 if (RT_SUCCESS(rc))
280 {
281 if (g_u32ClientHandleCount <= u32ClientHandleCount)
282 g_u32ClientHandleCount = u32ClientHandleCount;
283 hgcmObjLeave ();
284 }
285}
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