VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use