Changeset 38157 in vbox
- Timestamp:
- Jul 25, 2011 1:10:12 PM (13 years ago)
- Location:
- trunk/src/VBox/Additions/common/VBoxService
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
r38133 r38157 20 20 * Header Files * 21 21 *******************************************************************************/ 22 #include <iprt/asm.h> 22 23 #include <iprt/assert.h> 23 24 #include <iprt/getopt.h> … … 40 41 /** The semaphore we're blocking on. */ 41 42 static RTSEMEVENTMULTI g_hControlEvent = NIL_RTSEMEVENTMULTI; 42 /** The Guest Control service client ID. */43 /** The guest control service client ID. */ 43 44 static uint32_t g_GuestControlSvcClientID = 0; 44 /** List of spawned processes. */ 45 RTLISTNODE g_GuestControlExecThreads; 45 /** How many started guest processes are kept into memory for supplying 46 * information to the host. Default is 5 processes. If 0 is specified, 47 * the maximum number of processes is unlimited. */ 48 uint32_t g_GuestControlProcsMaxKept = 5; 49 /** List of guest control threads. */ 50 RTLISTNODE g_GuestControlThreads; 46 51 /** Critical section protecting g_GuestControlExecThreads. */ 47 RTCRITSECT g_GuestControl ExecThreadsCritSect;52 RTCRITSECT g_GuestControlThreadsCritSect; 48 53 49 54 /** @copydoc VBOXSERVICE::pfnPreInit */ 50 55 static DECLCALLBACK(int) VBoxServiceControlPreInit(void) 51 56 { 57 #ifdef VBOX_WITH_GUEST_PROPS 58 /* 59 * Read the service options from the VM's guest properties. 60 * Note that these options can be overridden by the command line options later. 61 */ 62 uint32_t uGuestPropSvcClientID; 63 int rc = VbglR3GuestPropConnect(&uGuestPropSvcClientID); 64 if (RT_FAILURE(rc)) 65 { 66 if (rc == VERR_HGCM_SERVICE_NOT_FOUND) /* Host service is not available. */ 67 { 68 VBoxServiceVerbose(0, "Control: Guest property service is not available, skipping\n"); 69 rc = VINF_SUCCESS; 70 } 71 else 72 VBoxServiceError("Control: Failed to connect to the guest property service! Error: %Rrc\n", rc); 73 } 74 else 75 { 76 rc = VBoxServiceReadPropUInt32(uGuestPropSvcClientID, "/VirtualBox/GuestAdd/VBoxService/--control-procs-max-kept", 77 &g_GuestControlProcsMaxKept, 0, UINT32_MAX - 1); 78 79 VbglR3GuestPropDisconnect(uGuestPropSvcClientID); 80 } 81 82 if (rc == VERR_NOT_FOUND) /* If a value is not found, don't be sad! */ 83 rc = VINF_SUCCESS; 84 return rc; 85 #else 86 /* Nothing to do here yet. */ 52 87 return VINF_SUCCESS; 88 #endif 53 89 } 54 90 … … 63 99 rc = VBoxServiceArgUInt32(argc, argv, "", pi, 64 100 &g_ControlInterval, 1, UINT32_MAX - 1); 101 else if (!strcmp(argv[*pi], "--control-procs-max-kept")) 102 rc = VBoxServiceArgUInt32(argc, argv, "", pi, 103 &g_GuestControlProcsMaxKept, 0, UINT32_MAX - 1); 65 104 return rc; 66 105 } … … 83 122 if (RT_SUCCESS(rc)) 84 123 { 85 VBoxServiceVerbose(3, "Control: Service Client ID: %#x\n", g_GuestControlSvcClientID);124 VBoxServiceVerbose(3, "Control: Service client ID: %#x\n", g_GuestControlSvcClientID); 86 125 87 126 /* Init thread list. */ 88 RTListInit(&g_GuestControl ExecThreads);89 rc = RTCritSectInit(&g_GuestControl ExecThreadsCritSect);127 RTListInit(&g_GuestControlThreads); 128 rc = RTCritSectInit(&g_GuestControlThreadsCritSect); 90 129 AssertRC(rc); 91 130 } … … 213 252 } 214 253 254 void VBoxServiceControlThreadSignalShutdown(const PVBOXSERVICECTRLTHREAD pThread) 255 { 256 AssertPtrReturnVoid(pThread); 257 ASMAtomicXchgBool(&pThread->fShutdown, true); 258 } 259 260 261 int VBoxServiceControlThreadWaitForShutdown(const PVBOXSERVICECTRLTHREAD pThread) 262 { 263 AssertPtrReturn(pThread, VERR_INVALID_POINTER); 264 int rc = VINF_SUCCESS; 265 if (pThread->Thread != NIL_RTTHREAD) 266 { 267 /* Wait a bit ... */ 268 rc = RTThreadWait(pThread->Thread, 30 * 1000 /* Wait 30 seconds max. */, NULL); 269 } 270 return rc; 271 } 272 273 274 static void VBoxServiceControlDestroyThreads(void) 275 { 276 VBoxServiceVerbose(3, "Control: Destroying threads ...\n"); 277 278 int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect); 279 if (RT_SUCCESS(rc)) 280 { 281 /* Signal all threads that we want to shutdown. */ 282 PVBOXSERVICECTRLTHREAD pNode; 283 RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node) 284 VBoxServiceControlThreadSignalShutdown(pNode); 285 286 /* Wait for threads to shutdown. */ 287 RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node) 288 { 289 int rc2 = VBoxServiceControlThreadWaitForShutdown(pNode); 290 if (RT_FAILURE(rc2)) 291 VBoxServiceError("Control: Thread failed to stop; rc2=%Rrc\n", rc2); 292 293 /* Destroy thread specific data. */ 294 switch (pNode->enmType) 295 { 296 case kVBoxServiceCtrlThreadDataExec: 297 VBoxServiceControlExecThreadDataDestroy((PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData); 298 break; 299 300 default: 301 break; 302 } 303 } 304 305 /* Finally destroy thread list. */ 306 pNode = RTListGetFirst(&g_GuestControlThreads, VBOXSERVICECTRLTHREAD, Node); 307 while (pNode) 308 { 309 PVBOXSERVICECTRLTHREAD pNext = RTListNodeGetNext(&pNode->Node, VBOXSERVICECTRLTHREAD, Node); 310 bool fLast = RTListNodeIsLast(&g_GuestControlThreads, &pNode->Node); 311 312 RTListNodeRemove(&pNode->Node); 313 RTMemFree(pNode); 314 315 if (fLast) 316 break; 317 318 pNode = pNext; 319 } 320 321 int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect); 322 if (RT_SUCCESS(rc)) 323 rc = rc2; 324 } 325 RTCritSectDelete(&g_GuestControlThreadsCritSect); 326 } 327 215 328 216 329 /** @copydoc VBOXSERVICE::pfnTerm */ … … 219 332 VBoxServiceVerbose(3, "Control: Terminating ...\n"); 220 333 221 VBoxServiceControl ExecThreadsShutdown();334 VBoxServiceControlDestroyThreads(); 222 335 223 336 VbglR3GuestCtrlDisconnect(g_GuestControlSvcClientID); … … 242 355 "Host-driven Guest Control", 243 356 /* pszUsage. */ 244 " [--control-interval <ms>]"357 " [--control-interval <ms>] [--control-procs-max-kept <x>]" 245 358 , 246 359 /* pszOptions. */ 247 360 " --control-interval Specifies the interval at which to check for\n" 248 361 " new control commands. The default is 1000 ms.\n" 362 " --control-procs-max-kept\n" 363 " Specifies how many started guest processes are\n" 364 " kept into memory to work with.\n" 249 365 , 250 366 /* methods */ -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
r38115 r38157 47 47 using namespace guestControl; 48 48 49 extern RTLISTNODE g_GuestControl ExecThreads;50 extern RTCRITSECT g_GuestControl ExecThreadsCritSect;49 extern RTLISTNODE g_GuestControlThreads; 50 extern RTCRITSECT g_GuestControlThreadsCritSect; 51 51 52 52 … … 1135 1135 const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS) 1136 1136 { 1137 int rc; 1138 1137 int rc = VBoxServiceControlExecThreadsApplyPolicies(); 1138 if (RT_FAILURE(rc)) 1139 return rc; 1140 1141 /* 1142 * Allocate new thread data and assign it to our thread list. 1143 */ 1139 1144 PVBOXSERVICECTRLTHREAD pThread = (PVBOXSERVICECTRLTHREAD)RTMemAlloc(sizeof(VBOXSERVICECTRLTHREAD)); 1140 1145 if (pThread) … … 1176 1181 { 1177 1182 pThread->fStarted = true; 1178 /*rc =*/ RTListAppend(&g_GuestControl ExecThreads, &pThread->Node);1183 /*rc =*/ RTListAppend(&g_GuestControlThreads, &pThread->Node); 1179 1184 } 1180 1185 } 1181 1186 1182 1187 if (RT_FAILURE(rc)) 1183 VBoxServiceControlExecThreadD estroy((PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData);1188 VBoxServiceControlExecThreadDataDestroy((PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData); 1184 1189 } 1185 1190 if (RT_FAILURE(rc)) -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp
r38113 r38157 20 20 * Header Files * 21 21 *******************************************************************************/ 22 #include <iprt/asm.h>23 22 #include <iprt/assert.h> 24 23 #include <iprt/getopt.h> … … 33 32 #include "VBoxServiceControlExecThread.h" 34 33 35 extern RTLISTNODE g_GuestControlExecThreads; 36 extern RTCRITSECT g_GuestControlExecThreadsCritSect; 34 extern uint32_t g_GuestControlProcsMaxKept; 35 extern RTLISTNODE g_GuestControlThreads; 36 extern RTCRITSECT g_GuestControlThreadsCritSect; 37 37 38 38 const PVBOXSERVICECTRLTHREAD vboxServiceControlExecThreadGetByPID(uint32_t uPID); 39 int VBoxServiceControlExecThreadShutdown(const PVBOXSERVICECTRLTHREAD pThread); 39 40 40 41 /** … … 154 155 155 156 if (RT_FAILURE(rc)) 156 VBoxServiceControlExecThreadD estroy(pData);157 VBoxServiceControlExecThreadDataDestroy(pData); 157 158 return rc; 158 159 } … … 160 161 161 162 /** 162 * Frees an allocated thread data structure along with all its allocated parameters. 163 * 164 * @param pData Pointer to thread data to free. 165 */ 166 void VBoxServiceControlExecThreadDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pData) 167 { 168 if (pData) 169 { 170 VBoxServiceVerbose(3, "ControlExec: [PID %u]: Destroying thread ...\n", 171 pData->uPID); 172 173 RTStrFree(pData->pszCmd); 174 if (pData->uNumEnvVars) 175 { 176 for (uint32_t i = 0; i < pData->uNumEnvVars; i++) 177 RTStrFree(pData->papszEnv[i]); 178 RTMemFree(pData->papszEnv); 179 } 180 RTGetOptArgvFree(pData->papszArgs); 181 RTStrFree(pData->pszUser); 182 RTStrFree(pData->pszPassword); 183 184 VBoxServicePipeBufDestroy(&pData->stdOut); 185 VBoxServicePipeBufDestroy(&pData->stdErr); 186 VBoxServicePipeBufDestroy(&pData->stdIn); 187 188 RTMemFree(pData); 189 pData = NULL; 190 } 191 } 192 193 163 * Applies the policies to all guest execution threads. 164 * 165 * @return IPRT status code. 166 */ 167 int VBoxServiceControlExecThreadsApplyPolicies(void) 168 { 169 int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect); 170 if (RT_SUCCESS(rc)) 171 { 172 VBoxServiceVerbose(2, "Control: Applying policies ...\n"); 173 174 /* 175 * Check if we're respecting our memory policy by checking 176 * how many guest processes are started and served already. 177 */ 178 if (g_GuestControlProcsMaxKept) /* If we allow unlimited processes, take a shortcut. */ 179 { 180 uint32_t uNumProcs = 0; 181 PVBOXSERVICECTRLTHREAD pNode; 182 RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node) 183 { 184 if (pNode->enmType == kVBoxServiceCtrlThreadDataExec) 185 uNumProcs++; 186 } 187 188 /* 189 * Do we serve more guest processes than we should? Kill the oldest n ones (=beginning 190 * at the list). 191 */ 192 uint32_t uProcsToKill = 0; 193 if (uNumProcs > g_GuestControlProcsMaxKept) 194 uProcsToKill = uNumProcs - g_GuestControlProcsMaxKept; 195 if (uProcsToKill) 196 { 197 VBoxServiceVerbose(2, "Control: Maximum guest processes set to %u, running %u, killing %u oldest one(s) ...\n", 198 g_GuestControlProcsMaxKept, uNumProcs, uProcsToKill); 199 200 RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node) 201 { 202 PVBOXSERVICECTRLTHREAD pNext = RTListNodeGetNext(&pNode->Node, VBOXSERVICECTRLTHREAD, Node); 203 204 rc = VBoxServiceControlExecThreadShutdown(pNode); 205 if (RT_FAILURE(rc)) 206 { 207 VBoxServiceError("Control: Unable to shut down thread due to policy, rc=%Rrc", rc); 208 /* Keep going. */ 209 } 210 211 RTListNodeRemove(&pNode->Node); 212 RTMemFree(pNode); 213 pNode = pNext; 214 215 /* Did we fullfill our rate? Then stop killing innocent guest processes. */ 216 if (--uProcsToKill == 0) 217 break; 218 } 219 } 220 } 221 222 int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect); 223 if (RT_SUCCESS(rc)) 224 rc = rc2; 225 } 226 227 return rc; 228 } 229 230 231 /** 232 * Assigns a valid PID to a guest control thread and also checks if there already was 233 * another (stale) guest process which was using that PID before and destroys it. 234 * 235 * @return IPRT status code. 236 * @param pData Pointer to guest control execution thread data. 237 * @param uPID PID to assign to the specified guest control execution thread. 238 */ 194 239 int VBoxServiceControlExecThreadAssignPID(PVBOXSERVICECTRLTHREADDATAEXEC pData, uint32_t uPID) 195 240 { … … 197 242 AssertReturn(uPID, VERR_INVALID_PARAMETER); 198 243 199 int rc = RTCritSectEnter(&g_GuestControl ExecThreadsCritSect);244 int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect); 200 245 if (RT_SUCCESS(rc)) 201 246 { 202 247 /* Search an old thread using the desired PID and shut it down completely -- it's 203 248 * not used anymore. */ 204 const PVBOXSERVICECTRLTHREAD pOldThread = vboxServiceControlExecThreadGetByPID(uPID); 205 if ( pOldThread 206 && pOldThread->pvData != pData) 207 { 249 PVBOXSERVICECTRLTHREAD pOldNode = vboxServiceControlExecThreadGetByPID(uPID); 250 if ( pOldNode 251 && pOldNode->pvData != pData) 252 { 253 PVBOXSERVICECTRLTHREAD pNext = RTListNodeGetNext(&pOldNode->Node, VBOXSERVICECTRLTHREAD, Node); 254 208 255 VBoxServiceVerbose(3, "ControlExec: PID %u was used before, shutting down stale exec thread ...\n", 209 256 uPID); 210 AssertPtr(pOldThread->pvData); 211 VBoxServiceControlExecThreadDestroy((PVBOXSERVICECTRLTHREADDATAEXEC)pOldThread->pvData); 212 } 213 /** @todo Remove node from thread list! */ 257 AssertPtr(pOldNode->pvData); 258 rc = VBoxServiceControlExecThreadShutdown(pOldNode); 259 if (RT_FAILURE(rc)) 260 { 261 VBoxServiceVerbose(3, "ControlExec: Unable to shut down stale exec thread, rc=%Rrc\n", rc); 262 /* Keep going. */ 263 } 264 265 RTListNodeRemove(&pOldNode->Node); 266 RTMemFree(pOldNode); 267 } 214 268 215 269 /* Assign PID to current thread. */ … … 219 273 VBoxServicePipeBufSetPID(&pData->stdErr, pData->uPID); 220 274 221 int rc2 = RTCritSectLeave(&g_GuestControl ExecThreadsCritSect);275 int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect); 222 276 if (RT_SUCCESS(rc)) 223 277 rc = rc2; … … 229 283 230 284 /** 285 * Frees an allocated thread data structure along with all its allocated parameters. 286 * 287 * @param pData Pointer to thread data to free. 288 */ 289 void VBoxServiceControlExecThreadDataDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pData) 290 { 291 if (pData) 292 { 293 VBoxServiceVerbose(3, "ControlExec: [PID %u]: Destroying thread data ...\n", 294 pData->uPID); 295 296 RTStrFree(pData->pszCmd); 297 if (pData->uNumEnvVars) 298 { 299 for (uint32_t i = 0; i < pData->uNumEnvVars; i++) 300 RTStrFree(pData->papszEnv[i]); 301 RTMemFree(pData->papszEnv); 302 } 303 RTGetOptArgvFree(pData->papszArgs); 304 RTStrFree(pData->pszUser); 305 RTStrFree(pData->pszPassword); 306 307 VBoxServicePipeBufDestroy(&pData->stdOut); 308 VBoxServicePipeBufDestroy(&pData->stdErr); 309 VBoxServicePipeBufDestroy(&pData->stdIn); 310 311 RTMemFree(pData); 312 pData = NULL; 313 } 314 } 315 316 317 /** 231 318 * Finds a (formerly) started process given by its PID. 232 319 * Internal function, does not do locking -- this must be done from the caller function! … … 238 325 { 239 326 PVBOXSERVICECTRLTHREAD pNode = NULL; 240 RTListForEach(&g_GuestControl ExecThreads, pNode, VBOXSERVICECTRLTHREAD, Node)327 RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node) 241 328 { 242 329 if ( pNode->fStarted … … 267 354 AssertPtrReturn(pBuf, VERR_INVALID_PARAMETER); 268 355 269 int rc = RTCritSectEnter(&g_GuestControl ExecThreadsCritSect);356 int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect); 270 357 if (RT_SUCCESS(rc)) 271 358 { … … 295 382 else 296 383 rc = VERR_NOT_FOUND; /* PID not found! */ 297 RTCritSectLeave(&g_GuestControl ExecThreadsCritSect);384 RTCritSectLeave(&g_GuestControlThreadsCritSect); 298 385 } 299 386 return rc; … … 318 405 AssertReturn(cbSize, VERR_INVALID_PARAMETER); 319 406 320 int rc = RTCritSectEnter(&g_GuestControl ExecThreadsCritSect);407 int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect); 321 408 if (RT_SUCCESS(rc)) 322 409 { … … 381 468 rc = VERR_NOT_FOUND; /* PID not found! */ 382 469 383 int rc2 = RTCritSectLeave(&g_GuestControl ExecThreadsCritSect);470 int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect); 384 471 if (RT_SUCCESS(rc)) 385 472 rc = rc2; … … 388 475 } 389 476 390 391 /** 392 * Gracefully shuts down all process execution threads. 393 * 394 */ 395 void VBoxServiceControlExecThreadsShutdown(void) 396 { 397 int rc = RTCritSectEnter(&g_GuestControlExecThreadsCritSect); 398 if (RT_SUCCESS(rc)) 399 { 400 /* Signal all threads that we want to shutdown. */ 401 PVBOXSERVICECTRLTHREAD pNode; 402 RTListForEach(&g_GuestControlExecThreads, pNode, VBOXSERVICECTRLTHREAD, Node) 403 ASMAtomicXchgBool(&pNode->fShutdown, true); 404 405 /* Wait for threads to shutdown. */ 406 RTListForEach(&g_GuestControlExecThreads, pNode, VBOXSERVICECTRLTHREAD, Node) 407 { 408 if (pNode->Thread != NIL_RTTHREAD) 409 { 410 /* Wait a bit ... */ 411 int rc2 = RTThreadWait(pNode->Thread, 30 * 1000 /* Wait 30 seconds max. */, NULL); 412 if (RT_FAILURE(rc2)) 413 VBoxServiceError("Control: Thread failed to stop; rc2=%Rrc\n", rc2); 414 } 415 416 /* Destroy thread specific data. */ 417 switch (pNode->enmType) 418 { 419 case kVBoxServiceCtrlThreadDataExec: 420 VBoxServiceControlExecThreadDestroy((PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData); 421 break; 422 423 default: 424 break; 425 } 426 } 427 428 /* Finally destroy thread list. */ 429 pNode = RTListGetFirst(&g_GuestControlExecThreads, VBOXSERVICECTRLTHREAD, Node); 430 while (pNode) 431 { 432 PVBOXSERVICECTRLTHREAD pNext = RTListNodeGetNext(&pNode->Node, VBOXSERVICECTRLTHREAD, Node); 433 bool fLast = RTListNodeIsLast(&g_GuestControlExecThreads, &pNode->Node); 434 435 RTListNodeRemove(&pNode->Node); 436 RTMemFree(pNode); 437 438 if (fLast) 439 break; 440 441 pNode = pNext; 442 } 443 444 int rc2 = RTCritSectLeave(&g_GuestControlExecThreadsCritSect); 445 if (RT_SUCCESS(rc)) 446 rc = rc2; 447 } 448 RTCritSectDelete(&g_GuestControlExecThreadsCritSect); 449 } 450 477 int VBoxServiceControlExecThreadShutdown(const PVBOXSERVICECTRLTHREAD pThread) 478 { 479 AssertPtrReturn(pThread, VERR_INVALID_POINTER); 480 481 if (pThread->enmType == kVBoxServiceCtrlThreadDataExec) 482 { 483 PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData; 484 if (!pData) 485 return VINF_SUCCESS; 486 VBoxServiceVerbose(2, "Control: [PID %u]: Will not be served anymore\n", 487 pData->uPID); 488 VBoxServiceControlExecThreadDataDestroy(pData); 489 } 490 491 VBoxServiceControlThreadSignalShutdown(pThread); 492 return VBoxServiceControlThreadWaitForShutdown(pThread); 493 } -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.h
r38113 r38157 27 27 const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars, 28 28 const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS); 29 int VBoxServiceControlExecThreadsApplyPolicies(); 29 30 int VBoxServiceControlExecThreadAssignPID(PVBOXSERVICECTRLTHREADDATAEXEC pData, uint32_t uPID); 30 void VBoxServiceControlExecThreadDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pData); 31 void VBoxServiceControlExecThreadDataDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pData); 32 int VBoxServiceControlExecThreadGetOutput(uint32_t uPID, uint32_t uHandleId, uint32_t uTimeout, 33 uint8_t *pBuf, uint32_t cbSize, uint32_t *pcbRead); 31 34 int VBoxServiceControlExecThreadSetInput(uint32_t uPID, bool fPendingClose, uint8_t *pBuf, 32 35 uint32_t cbSize, uint32_t *pcbWritten); 33 int VBoxServiceControlExecThreadGetOutput(uint32_t uPID, uint32_t uHandleId, uint32_t uTimeout,34 uint8_t *pBuf, uint32_t cbSize, uint32_t *pcbRead);35 void VBoxServiceControlExecThreadsShutdown(void);36 37 36 #endif /* !___VBoxServiceControlExecThread_h */ 38 37 -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
r38113 r38157 305 305 306 306 #ifdef VBOX_WITH_GUEST_CONTROL 307 extern int VBoxServiceGCtrlDirClose(uint32_t u32ClientId, uint32_t uNumParms); 308 extern int VBoxServiceGCtrlDirOpen(uint32_t u32ClientId, uint32_t uNumParms); 309 extern int VBoxServiceGCtrlDirRead(uint32_t u32ClientId, uint32_t uNumParms); 307 extern void VBoxServiceControlThreadSignalShutdown(const PVBOXSERVICECTRLTHREAD pThread); 308 extern int VBoxServiceControlThreadWaitForShutdown(const PVBOXSERVICECTRLTHREAD pThread); 310 309 311 310 extern int VBoxServiceControlExecHandleCmdStartProcess(uint32_t u32ClientId, uint32_t uNumParms); … … 316 315 const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars, 317 316 const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS); 318 extern void VBoxServiceControlExecThreadD estroy(PVBOXSERVICECTRLTHREADDATAEXEC pThread);317 extern void VBoxServiceControlExecThreadDataDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pThread); 319 318 #endif /* VBOX_WITH_GUEST_CONTROL */ 320 319
Note:
See TracChangeset
for help on using the changeset viewer.