~ubuntu-branches/ubuntu/precise/virtualbox/precise-updates

« back to all changes in this revision

Viewing changes to src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-10-17 23:23:09 UTC
  • mfrom: (3.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20111017232309-kzm6841lzk61ranj
Tags: 4.1.4-dfsg-1
* New upstream release.
  - Fixes missing icons when using pt_BR locale. (Closes: #507188)
  - Fixes guest additions download url. (Closes: #637349; LP: #840668)
* Refresh patches.
* Drop the vboxmouse x11 driver. The mouse integration is now completely
  handled by the kernel module.
* Restrict dh_pycentral to the virtualbox binary package.
* Merge changes from the Ubuntu package but use them only when built
  on Ubuntu:
  - Add an Apport hook.
  - Add vboxguest modalias to the package control field.
* Pass KBUILD_VERBOSE=2 to kmk.
* Add 36-fix-text-mode.patch to fix text mode when using the vboxvideo driver.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: VBoxServiceControlExecThread.cpp 38445 2011-08-12 20:43:24Z vboxsync $ */
 
1
/* $Id: VBoxServiceControlExecThread.cpp $ */
2
2
/** @file
3
3
 * VBoxServiceControlExecThread - Thread for an executed guest process.
4
4
 */
338
338
    int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
339
339
    if (RT_SUCCESS(rc))
340
340
    {
341
 
        const PVBOXSERVICECTRLTHREAD pNode = vboxServiceControlExecThreadGetByPID(uPID);
342
 
        if (pNode)
 
341
        const PVBOXSERVICECTRLTHREAD pThread = vboxServiceControlExecThreadGetByPID(uPID);
 
342
        if (pThread)
343
343
        {
344
 
            const PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData;
 
344
            const PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData;
345
345
            AssertPtr(pData);
346
346
 
347
347
            PVBOXSERVICECTRLEXECPIPEBUF pPipeBuf = NULL;
348
348
            switch (uHandleId)
349
349
            {
350
 
                case OUTPUT_HANDLE_ID_STDERR: /* StdErr */
 
350
                case OUTPUT_HANDLE_ID_STDERR:
351
351
                    pPipeBuf = &pData->stdErr;
352
352
                    break;
353
353
 
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;
356
357
                    break;
357
358
 
358
359
                default:
359
 
                    AssertReleaseMsgFailed(("Unknown output handle ID (%u)\n", uHandleId));
 
360
                    rc = VERR_NOT_FOUND; /* Handle ID not found! */
360
361
                    break;
361
362
            }
362
 
            AssertPtr(pPipeBuf);
363
363
 
364
 
#ifdef DEBUG_andy
365
 
            VBoxServiceVerbose(4, "ControlExec: [PID %u]: Getting output from pipe buffer %u ...\n",
366
 
                               uPID, pPipeBuf->uPipeId);
367
 
#endif
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
370
 
             * data read. */
371
 
            bool fEnabled = VBoxServicePipeBufIsEnabled(pPipeBuf);
372
 
            if (fEnabled)
373
 
            {
374
 
#ifdef DEBUG_andy
375
 
                VBoxServiceVerbose(4, "ControlExec: [PID %u]: Waiting for pipe buffer %u (%ums)\n",
376
 
                                   uPID, pPipeBuf->uPipeId, uTimeout);
377
 
#endif
378
 
                rc = VBoxServicePipeBufWaitForEvent(pPipeBuf, uTimeout);
379
 
            }
380
364
            if (RT_SUCCESS(rc))
381
365
            {
382
 
                uint32_t cbRead = cbSize;
383
 
                rc = VBoxServicePipeBufRead(pPipeBuf, pBuf, cbSize, &cbRead);
 
366
                AssertPtr(pPipeBuf);
 
367
 
 
368
    #ifdef DEBUG_andy
 
369
                VBoxServiceVerbose(4, "ControlExec: [PID %u]: Getting output from pipe buffer %u ...\n",
 
370
                                   uPID, pPipeBuf->uPipeId);
 
371
    #endif
 
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
 
374
                 * data read. */
 
375
                bool fEnabled = VBoxServicePipeBufIsEnabled(pPipeBuf);
 
376
                if (fEnabled)
 
377
                {
 
378
    #ifdef DEBUG_andy
 
379
                    VBoxServiceVerbose(4, "ControlExec: [PID %u]: Waiting for pipe buffer %u (%ums)\n",
 
380
                                       uPID, pPipeBuf->uPipeId, uTimeout);
 
381
    #endif
 
382
                    rc = VBoxServicePipeBufWaitForEvent(pPipeBuf, uTimeout);
 
383
                }
384
384
                if (RT_SUCCESS(rc))
385
385
                {
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));
389
 
                    if (pcbRead)
390
 
                        *pcbRead = cbRead;
 
386
                    uint32_t cbRead = cbSize; /* Read as much as possible. */
 
387
                    rc = VBoxServicePipeBufRead(pPipeBuf, pBuf, cbSize, &cbRead);
 
388
                    if (RT_SUCCESS(rc))
 
389
                    {
 
390
                        if (   !cbRead
 
391
                            && fEnabled)
 
392
                        {
 
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));
 
396
                        }
 
397
                        if (pcbRead)
 
398
                            *pcbRead = cbRead;
 
399
                    }
 
400
                    else
 
401
                        VBoxServiceError("ControlExec: [PID %u]: Unable to read from pipe buffer %u, rc=%Rrc\n",
 
402
                                         uPID, pPipeBuf->uPipeId, rc);
391
403
                }
392
 
                else
393
 
                    VBoxServiceError("ControlExec: [PID %u]: Unable to read from pipe buffer %u, rc=%Rrc\n",
394
 
                                     uPID, pPipeBuf->uPipeId, rc);
395
404
            }
396
405
        }
397
406
        else
405
414
}
406
415
 
407
416
 
 
417
int VBoxServiceControlExecThreadRemove(uint32_t uPID)
 
418
{
 
419
    int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
 
420
    if (RT_SUCCESS(rc))
 
421
    {
 
422
        PVBOXSERVICECTRLTHREAD pThread = vboxServiceControlExecThreadGetByPID(uPID);
 
423
        if (pThread)
 
424
        {
 
425
            Assert(pThread->fStarted != pThread->fStopped);
 
426
            if (pThread->fStopped) /* Only shut down stopped threads. */
 
427
            {
 
428
                VBoxServiceVerbose(4, "ControlExec: [PID %u]: Removing thread ... \n",
 
429
                                   uPID);
 
430
 
 
431
                rc = VBoxServiceControlExecThreadShutdown(pThread);
 
432
 
 
433
                RTListNodeRemove(&pThread->Node);
 
434
                RTMemFree(pThread);
 
435
            }
 
436
        }
 
437
        else
 
438
            rc = VERR_NOT_FOUND;
 
439
 
 
440
        int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect);
 
441
        if (RT_SUCCESS(rc))
 
442
            rc = rc2;
 
443
    }
 
444
 
 
445
    return rc;
 
446
}
 
447
 
 
448
/* Does not do locking, must be done by the caller! */
408
449
int VBoxServiceControlExecThreadShutdown(const PVBOXSERVICECTRLTHREAD pThread)
409
450
{
410
451
    AssertPtrReturn(pThread, VERR_INVALID_POINTER);
433
474
 
434
475
int VBoxServiceControlExecThreadStartAllowed(bool *pbAllowed)
435
476
{
 
477
    AssertPtrReturn(pbAllowed, VERR_INVALID_POINTER);
 
478
 
436
479
    int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
437
480
    if (RT_SUCCESS(rc))
438
481
    {
441
484
         * how many guest processes are started and served already.
442
485
         */
443
486
        bool fLimitReached = false;
444
 
        if (g_GuestControlProcsMaxKept) /* If we allow unlimited processes, take a shortcut. */
 
487
        if (g_GuestControlProcsMaxKept) /* If we allow unlimited processes (=0), take a shortcut. */
445
488
        {
446
489
            /** @todo Put running/stopped (+ memory alloc) stats into global struct! */
447
490
            uint32_t uProcsRunning = 0;
467
510
            int32_t iProcsLeft = (g_GuestControlProcsMaxKept - uProcsRunning - 1);
468
511
            if (iProcsLeft < 0)
469
512
            {
470
 
                VBoxServiceVerbose(3, "ControlExec: Maximum running guest processes reached\n");
 
513
                VBoxServiceVerbose(3, "ControlExec: Maximum running guest processes reached (%u)\n",
 
514
                                   g_GuestControlProcsMaxKept);
471
515
                fLimitReached = true;
472
516
            }
473
517
            else if (uProcsStopped > (uint32_t)iProcsLeft)
486
530
                        int rc2 = VBoxServiceControlExecThreadShutdown(pNode);
487
531
                        if (RT_FAILURE(rc2))
488
532
                        {
489
 
                            VBoxServiceError("ControlExec: Unable to shut down thread due to policy, rc=%Rrc", rc2);
 
533
                            VBoxServiceError("ControlExec: Unable to shut down thread due to policy, rc=%Rrc\n", rc2);
490
534
                            if (RT_SUCCESS(rc))
491
535
                                rc = rc2;
492
536
                            /* Keep going. */
496
540
                        RTMemFree(pNode);
497
541
                        pNode = pNext;
498
542
 
 
543
                        Assert(uProcsToKill);
499
544
                        uProcsToKill--;
500
545
                        if (!uProcsToKill)
501
546
                            break;
502
 
 
503
547
                    }
504
548
                }
505
549
                Assert(uProcsToKill == 0);