338
338
int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
339
339
if (RT_SUCCESS(rc))
341
const PVBOXSERVICECTRLTHREAD pNode = vboxServiceControlExecThreadGetByPID(uPID);
341
const PVBOXSERVICECTRLTHREAD pThread = vboxServiceControlExecThreadGetByPID(uPID);
344
const PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData;
344
const PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData;
345
345
AssertPtr(pData);
347
347
PVBOXSERVICECTRLEXECPIPEBUF pPipeBuf = NULL;
348
348
switch (uHandleId)
350
case OUTPUT_HANDLE_ID_STDERR: /* StdErr */
350
case OUTPUT_HANDLE_ID_STDERR:
351
351
pPipeBuf = &pData->stdErr;
354
case OUTPUT_HANDLE_ID_STDOUT: /* StdOut */
354
case OUTPUT_HANDLE_ID_STDOUT:
355
case OUTPUT_HANDLE_ID_STDOUT_DEPRECATED:
355
356
pPipeBuf = &pData->stdOut;
359
AssertReleaseMsgFailed(("Unknown output handle ID (%u)\n", uHandleId));
360
rc = VERR_NOT_FOUND; /* Handle ID not found! */
365
VBoxServiceVerbose(4, "ControlExec: [PID %u]: Getting output from pipe buffer %u ...\n",
366
uPID, pPipeBuf->uPipeId);
368
/* If the stdout pipe buffer is enabled (that is, still could be filled by a running
369
* process) wait for the signal to arrive so that we don't return without any actual
371
bool fEnabled = VBoxServicePipeBufIsEnabled(pPipeBuf);
375
VBoxServiceVerbose(4, "ControlExec: [PID %u]: Waiting for pipe buffer %u (%ums)\n",
376
uPID, pPipeBuf->uPipeId, uTimeout);
378
rc = VBoxServicePipeBufWaitForEvent(pPipeBuf, uTimeout);
380
364
if (RT_SUCCESS(rc))
382
uint32_t cbRead = cbSize;
383
rc = VBoxServicePipeBufRead(pPipeBuf, pBuf, cbSize, &cbRead);
369
VBoxServiceVerbose(4, "ControlExec: [PID %u]: Getting output from pipe buffer %u ...\n",
370
uPID, pPipeBuf->uPipeId);
372
/* If the stdout pipe buffer is enabled (that is, still could be filled by a running
373
* process) wait for the signal to arrive so that we don't return without any actual
375
bool fEnabled = VBoxServicePipeBufIsEnabled(pPipeBuf);
379
VBoxServiceVerbose(4, "ControlExec: [PID %u]: Waiting for pipe buffer %u (%ums)\n",
380
uPID, pPipeBuf->uPipeId, uTimeout);
382
rc = VBoxServicePipeBufWaitForEvent(pPipeBuf, uTimeout);
384
384
if (RT_SUCCESS(rc))
386
if (fEnabled && !cbRead)
387
AssertMsgFailed(("[PID %u]: Waited (%ums) for pipe buffer %u (%u bytes left), but nothing read!\n",
388
uPID, uTimeout, pPipeBuf->uPipeId, pPipeBuf->cbSize - pPipeBuf->cbOffset));
386
uint32_t cbRead = cbSize; /* Read as much as possible. */
387
rc = VBoxServicePipeBufRead(pPipeBuf, pBuf, cbSize, &cbRead);
393
AssertReleaseMsg(!VBoxServicePipeBufIsEnabled(pPipeBuf),
394
("[PID %u]: Waited (%ums) for active pipe buffer %u (%u size, %u bytes left), but nothing read!\n",
395
uPID, uTimeout, pPipeBuf->uPipeId, pPipeBuf->cbSize, pPipeBuf->cbSize - pPipeBuf->cbOffset));
401
VBoxServiceError("ControlExec: [PID %u]: Unable to read from pipe buffer %u, rc=%Rrc\n",
402
uPID, pPipeBuf->uPipeId, rc);
393
VBoxServiceError("ControlExec: [PID %u]: Unable to read from pipe buffer %u, rc=%Rrc\n",
394
uPID, pPipeBuf->uPipeId, rc);
417
int VBoxServiceControlExecThreadRemove(uint32_t uPID)
419
int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
422
PVBOXSERVICECTRLTHREAD pThread = vboxServiceControlExecThreadGetByPID(uPID);
425
Assert(pThread->fStarted != pThread->fStopped);
426
if (pThread->fStopped) /* Only shut down stopped threads. */
428
VBoxServiceVerbose(4, "ControlExec: [PID %u]: Removing thread ... \n",
431
rc = VBoxServiceControlExecThreadShutdown(pThread);
433
RTListNodeRemove(&pThread->Node);
440
int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect);
448
/* Does not do locking, must be done by the caller! */
408
449
int VBoxServiceControlExecThreadShutdown(const PVBOXSERVICECTRLTHREAD pThread)
410
451
AssertPtrReturn(pThread, VERR_INVALID_POINTER);