Changeset 28983 in vbox for trunk/src/VBox/Additions
- Timestamp:
- May 3, 2010 2:55:34 PM (15 years ago)
- Location:
- trunk/src/VBox/Additions/common/VBoxService
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
r28968 r28983 25 25 #endif 26 26 27 #ifdef VBOX_WITH_GUEST_CONTROL 28 # include <iprt/list.h> 29 # include <iprt/semaphore.h> 30 #endif 27 #include <iprt/list.h> 28 #include <iprt/semaphore.h> 31 29 32 30 /** … … 222 220 { 223 221 /** The client ID for HGCM communication. */ 224 uint32_t uClientID;222 uint32_t uClientID; 225 223 RTLISTNODE Node; 224 RTSEMMUTEX Mutex; 226 225 } VBOXSERVICEVEPROPCACHE; 227 226 /** Pointer to a guest property cache. */ -
trunk/src/VBox/Additions/common/VBoxService/VBoxServicePropCache.cpp
r28981 r28983 36 36 { 37 37 AssertPtr(pCache); 38 /** @todo Prevent init the cache twice! */ 38 39 RTListInit(&pCache->Node); 39 40 pCache->uClientID = u32ClientId; 40 return VINF_SUCCESS;41 return RTSemMutexCreate(&pCache->Mutex); 41 42 } 42 43 … … 48 49 AssertPtr(pszName); 49 50 /* This is a O(n) lookup, maybe improve this later to O(1) using a map. */ 50 PVBOXSERVICEVEPROPCACHEENTRY pNode; 51 RTListForEach(&pCache->Node, pNode, VBOXSERVICEVEPROPCACHEENTRY, Node) 52 { 53 if (strcmp(pNode->pszName, pszName) == 0) 54 return pNode; 55 } 56 return NULL; 51 PVBOXSERVICEVEPROPCACHEENTRY pNodeIt, pNode = NULL; 52 if (RT_SUCCESS(RTSemMutexRequest(pCache->Mutex, RT_INDEFINITE_WAIT))) 53 { 54 RTListForEach(&pCache->Node, pNodeIt, VBOXSERVICEVEPROPCACHEENTRY, Node) 55 { 56 if (strcmp(pNodeIt->pszName, pszName) == 0) 57 { 58 pNode = pNodeIt; 59 break; 60 } 61 } 62 RTSemMutexRelease(pCache->Mutex); 63 } 64 return pNode; 57 65 } 58 66 … … 65 73 AssertPtr(pszName); 66 74 PVBOXSERVICEVEPROPCACHEENTRY pNode = VBoxServicePropCacheFind(pCache, pszName, 0); 75 int rc; 67 76 if (pNode != NULL) 68 77 { 69 pNode->uFlags = u32Flags; 70 if (pszValueReset) 71 { 78 rc = RTSemMutexRequest(pCache->Mutex, RT_INDEFINITE_WAIT); 79 if (RT_SUCCESS(rc)) 80 { 81 pNode->uFlags = u32Flags; 72 82 if (pszValueReset) 73 RTStrFree(pNode->pszValueReset); 74 pNode->pszValueReset = RTStrDup(pszValueReset); 75 } 76 return VINF_SUCCESS; 77 } 78 return VERR_NOT_FOUND; 83 { 84 if (pszValueReset) 85 RTStrFree(pNode->pszValueReset); 86 pNode->pszValueReset = RTStrDup(pszValueReset); 87 } 88 rc = RTSemMutexRelease(pCache->Mutex); 89 } 90 } 91 else 92 rc = VERR_NOT_FOUND; 93 return rc; 79 94 } 80 95 … … 136 151 137 152 PVBOXSERVICEVEPROPCACHEENTRY pNode = VBoxServicePropCacheFind(pCache, pszName, 0); 138 if (pNode == NULL) 139 { 140 pNode = (PVBOXSERVICEVEPROPCACHEENTRY)RTMemAlloc(sizeof(VBOXSERVICEVEPROPCACHEENTRY)); 141 AssertPtrReturn(pNode, VERR_NO_MEMORY); 142 143 pNode->pszName = RTStrDup(pszName); 144 pNode->pszValue = NULL; 145 pNode->uFlags = 0; 146 pNode->pszValueReset = NULL; 147 148 /*rc =*/ RTListAppend(&pCache->Node, &pNode->Node); 149 } 150 151 int rc; 152 AssertPtr(pNode); 153 if (pszValue) /* Do we have a value to check for? */ 154 { 155 bool fUpdate = false; 156 /* Always update this property, no matter what? */ 157 if (pNode->uFlags & VBOXSERVICEPROPCACHEFLAG_ALWAYS_UPDATE) 158 fUpdate = true; 159 /* Did the value change so we have to update? */ 160 else if (pNode->pszValue && strcmp(pNode->pszValue, pszValue) != 0) 161 fUpdate = true; 162 /* No value stored at the moment but we have a value now? */ 163 else if (pNode->pszValue == NULL) 164 fUpdate = true; 165 166 if (fUpdate) 167 { 168 /* Write the update. */ 169 rc = VBoxServiceWritePropF(pCache->uClientID, pNode->pszName, pszValue); 170 if (pNode->pszValue) 153 154 /* Lock the cache. */ 155 int rc = RTSemMutexRequest(pCache->Mutex, RT_INDEFINITE_WAIT); 156 if (RT_SUCCESS(rc)) 157 { 158 159 if (pNode == NULL) 160 { 161 pNode = (PVBOXSERVICEVEPROPCACHEENTRY)RTMemAlloc(sizeof(VBOXSERVICEVEPROPCACHEENTRY)); 162 AssertPtrReturn(pNode, VERR_NO_MEMORY); 163 164 pNode->pszName = RTStrDup(pszName); 165 pNode->pszValue = NULL; 166 pNode->uFlags = 0; 167 pNode->pszValueReset = NULL; 168 169 /*rc =*/ RTListAppend(&pCache->Node, &pNode->Node); 170 } 171 172 AssertPtr(pNode); 173 if (pszValue) /* Do we have a value to check for? */ 174 { 175 bool fUpdate = false; 176 /* Always update this property, no matter what? */ 177 if (pNode->uFlags & VBOXSERVICEPROPCACHEFLAG_ALWAYS_UPDATE) 178 fUpdate = true; 179 /* Did the value change so we have to update? */ 180 else if (pNode->pszValue && strcmp(pNode->pszValue, pszValue) != 0) 181 fUpdate = true; 182 /* No value stored at the moment but we have a value now? */ 183 else if (pNode->pszValue == NULL) 184 fUpdate = true; 185 186 if (fUpdate) 187 { 188 /* Write the update. */ 189 rc = VBoxServiceWritePropF(pCache->uClientID, pNode->pszName, pszValue); 190 if (pNode->pszValue) 191 RTStrFree(pNode->pszValue); 192 pNode->pszValue = RTStrDup(pszValue); 193 } 194 else 195 rc = VINF_ALREADY_INITIALIZED; /* No update needed. */ 196 } 197 else 198 { 199 /* No value specified. Deletion (or no action required). */ 200 if (pNode->pszValue) /* Did we have a value before? Then the value needs to be deleted. */ 201 { 202 /* Delete property (but do not remove from cache) if not deleted yet. */ 203 rc = VBoxServiceWritePropF(pCache->uClientID, pNode->pszName, NULL); 171 204 RTStrFree(pNode->pszValue); 172 pNode->pszValue = RTStrDup(pszValue); 173 } 174 else 175 rc = VINF_ALREADY_INITIALIZED; /* No update needed. */ 176 } 177 else 178 { 179 /* No value specified. Deletion (or no action required). */ 180 if (pNode->pszValue) /* Did we have a value before? Then the value needs to be deleted. */ 181 { 182 /* Delete property (but do not remove from cache) if not deleted yet. */ 183 rc = VBoxServiceWritePropF(pCache->uClientID, pNode->pszName, NULL); 184 RTStrFree(pNode->pszValue); 185 pNode->pszValue = NULL; 186 } 187 else 188 rc = VINF_ALREADY_INITIALIZED; /* No update needed. */ 189 } 190 191 /* Update rest of the fields. */ 192 if (pszValueReset) 193 { 194 if (pNode->pszValueReset) 195 RTStrFree(pNode->pszValueReset); 196 pNode->pszValueReset = RTStrDup(pszValueReset); 197 } 198 if (u32Flags) 199 pNode->uFlags = u32Flags; 200 201 /* Delete temp stuff. */ 202 if (pszValue) 203 RTStrFree(pszValue); 205 pNode->pszValue = NULL; 206 } 207 else 208 rc = VINF_ALREADY_INITIALIZED; /* No update needed. */ 209 } 210 211 /* Update rest of the fields. */ 212 if (pszValueReset) 213 { 214 if (pNode->pszValueReset) 215 RTStrFree(pNode->pszValueReset); 216 pNode->pszValueReset = RTStrDup(pszValueReset); 217 } 218 if (u32Flags) 219 pNode->uFlags = u32Flags; 220 221 /* Delete temp stuff. */ 222 if (pszValue) 223 RTStrFree(pszValue); 224 225 /* Release cache. */ 226 int rc2 = RTSemMutexRelease(pCache->Mutex); 227 if (RT_SUCCESS(rc)) 228 rc2 = rc; 229 } 204 230 return rc; 205 231 } … … 242 268 pNode = pNext; 243 269 } 270 /* Destroy mutex. */ 271 RTSemMutexDestroy(pCache->Mutex); 244 272 } 245 273 #endif /* VBOX_WITH_GUEST_PROPS */
Note:
See TracChangeset
for help on using the changeset viewer.