ClientWatcher.cpp revision cc9b22310b11782c8ec2db965d2233156ddb679d
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * VirtualBox API client session crash watcher
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Copyright (C) 2006-2013 Oracle Corporation
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * This file is part of VirtualBox Open Source Edition (OSE), as
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * available from http://www.virtualbox.org. This file is free software;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * you can redistribute it and/or modify it under the terms of the GNU
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * General Public License (GPL) as published by the Free Software
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Foundation, in version 2 as it comes in the "COPYING" file of the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#if defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) || defined(VBOX_WITH_GENERIC_SESSION_WATCHER)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/** Table for adaptive timeouts. After an update the counter starts at the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * maximum value and decreases to 0, i.e. first the short timeouts are used
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * and then the longer ones. This minimizes the detection latency in the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * cases where a change is expected, for crashes. */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppostatic const RTMSINTERVAL s_aUpdateTimeoutSteps[] = { 500, 200, 100, 50, 20, 10, 5 };
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* signal the client watcher thread, should be exiting now */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* wait for termination */
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan#elif defined(RT_OS_OS2) || defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) || defined(VBOX_WITH_GENERIC_SESSION_WATCHER)
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANGVirtualBox::ClientWatcher::ClientWatcher(const ComObjPtr<VirtualBox> &pVirtualBox) :
19b65a69adc64b3289ccb2fc32b805782e3f4540sb#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) || defined(VBOX_WITH_GENERIC_SESSION_WATCHER)
c1c61f44e88f4c8c155272ee56d868043146096asb /* start with high timeouts, nothing to do */
f0ca1d9a12d54d304791bc74525e2010ca924726sb (void *)this,
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Sends a signal to the thread to rescan the clients/VMs having open sessions.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* sent an update request */
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna /* use short timeouts, as we expect changes */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram ASMAtomicUoWriteU8(&mUpdateAdaptCtr, RT_ELEMENTS(s_aUpdateTimeoutSteps) - 1);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Adds a process to the list of processes to be reaped. This call should be
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * followed by a call to update() to cause the necessary actions immediately,
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * in case the process crashes straight away.
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANGvoid VirtualBox::ClientWatcher::addProcess(RTPROCESS pid)
c1c61f44e88f4c8c155272ee56d868043146096asb /* @todo r=klaus, do the reaping on all platforms! */
d8a518c84b0b033745c344594c3478e1294f3a9aSriharsha Basavapatna * Thread worker function that watches the termination of all client processes
c1c61f44e88f4c8c155272ee56d868043146096asb * that have open sessions using IMachine::LockMachine()
c1c61f44e88f4c8c155272ee56d868043146096asbDECLCALLBACK(int) VirtualBox::ClientWatcher::worker(RTTHREAD /* thread */, void *pvUser)
c1c61f44e88f4c8c155272ee56d868043146096asb VirtualBox::ClientWatcher *that = (VirtualBox::ClientWatcher *)pvUser;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng typedef std::vector<ComObjPtr<Machine> > MachineVector;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng typedef std::vector<ComObjPtr<SessionMachine> > SessionMachineVector;
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna VirtualBoxBase::initializeComForThread();
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG /// @todo (dmik) processes reaping!
0e8b4070e8262256f51dbb1aae9d22fa2f1366fcsb /* VirtualBox has been early uninitialized, terminate */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* release the caller to let uninit() ever proceed */
34b64c01c6a2242177691e1420a386e2789f79dcWENTAO YANG DWORD rc = ::WaitForMultipleObjects((DWORD)(1 + cnt + cntSpawned),
c1c61f44e88f4c8c155272ee56d868043146096asb /* Restore the caller before using VirtualBox. If it fails, this
c1c61f44e88f4c8c155272ee56d868043146096asb * means VirtualBox is being uninitialized and we must terminate. */
c1c61f44e88f4c8c155272ee56d868043146096asb bool update = false;
c1c61f44e88f4c8c155272ee56d868043146096asb /* update event is signaled */
f0ca1d9a12d54d304791bc74525e2010ca924726sb else if (rc > WAIT_OBJECT_0 && rc <= (WAIT_OBJECT_0 + cnt))
f0ca1d9a12d54d304791bc74525e2010ca924726sb /* machine mutex is released */
f0ca1d9a12d54d304791bc74525e2010ca924726sb else if (rc > WAIT_ABANDONED_0 && rc <= (WAIT_ABANDONED_0 + cnt))
f0ca1d9a12d54d304791bc74525e2010ca924726sb /* machine mutex is abandoned due to client process termination */
f0ca1d9a12d54d304791bc74525e2010ca924726sb else if (rc > WAIT_OBJECT_0 + cnt && rc <= (WAIT_OBJECT_0 + cntSpawned))
f0ca1d9a12d54d304791bc74525e2010ca924726sb /* spawned VM process has terminated (normally or abnormally) */
f0ca1d9a12d54d304791bc74525e2010ca924726sb /* close old process handles */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram for (size_t i = 1 + cnt; i < 1 + cnt + cntSpawned; ++i)
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb // get reference to the machines list in VirtualBox
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb VirtualBox::MachinesOList &allMachines = that->mVirtualBox->getMachinesList();
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb // lock the machines list for reading
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb AutoReadLock thatLock(allMachines.getLockHandle() COMMA_LOCKVAL_SRC_POS);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* obtain a new set of opened machines */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (MachinesOList::iterator it = allMachines.begin();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /// @todo handle situations with more than 64 objects
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna AssertMsgBreak((1 + cnt) <= MAXIMUM_WAIT_OBJECTS,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ("MAXIMUM_WAIT_OBJECTS reached"));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna if ((*it)->isSessionOpenOrClosing(sm))
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna AutoReadLock smLock(sm COMMA_LOCKVAL_SRC_POS);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna Machine::ClientToken *ct = sm->getClientToken();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna LogFlowFunc(("UPDATE: direct session count = %d\n", cnt));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* obtain a new set of spawned machines */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (MachinesOList::iterator it = allMachines.begin();
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /// @todo handle situations with more than 64 objects
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna AssertMsgBreak((1 + cnt + cntSpawned) <= MAXIMUM_WAIT_OBJECTS,
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna ("MAXIMUM_WAIT_OBJECTS reached"));
34f94fbc7a730740933e4776ade5f74009afe4ceWENTAO YANG HRESULT hrc = (*it)->COMGETTER(SessionPID)(&pid);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna HANDLE ph = OpenProcess(SYNCHRONIZE, FALSE, pid);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna AssertMsg(ph != NULL, ("OpenProcess (pid=%d) failed with %d\n",
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna LogFlowFunc(("UPDATE: spawned session count = %d\n", cntSpawned));
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna // machines lock unwinds here
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* close old process handles */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (size_t i = 1 + cnt; i < 1 + cnt + cntSpawned; ++i)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* release sets of machines if any */
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna /// @todo (dmik) processes reaping!
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /* according to PMREF, 64 is the maximum for the muxwait list */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* VirtualBox has been early uninitialized, terminate */
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna /* release the caller to let uninit() ever proceed */
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna int vrc = RTSemEventWait(that->mUpdateReq, 500);
f0ca1d9a12d54d304791bc74525e2010ca924726sb /* Restore the caller before using VirtualBox. If it fails, this
f0ca1d9a12d54d304791bc74525e2010ca924726sb * means VirtualBox is being uninitialized and we must terminate. */
f0ca1d9a12d54d304791bc74525e2010ca924726sb bool update = false;
ba2e4443695ee6a6f420a35cd4fc3d3346d22932seb /* update event is signaled */
ba2e4443695ee6a6f420a35cd4fc3d3346d22932seb AssertMsg(vrc == VERR_TIMEOUT || vrc == VERR_INTERRUPTED,
ba2e4443695ee6a6f420a35cd4fc3d3346d22932seb /* are there any mutexes? */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* figure out what's going on with machines */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo unsigned long semId = 0;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* machine mutex is normally released */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#if 0//def DEBUG
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo AutoReadLock machineLock(machines[semId] COMMA_LOCKVAL_SRC_POS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* machine mutex is abandoned due to client process
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * termination; find which mutex is in the Owner Died
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo unsigned long reqCnt;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo arc = DosQueryMutexSem((HMTX)handles[i].hsemCur, &pid, &tid, &reqCnt);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* close the dead mutex as asked by PMREF */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (i >= 0 && i < cnt)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#if 0//def DEBUG
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo AutoReadLock machineLock(machines[semId] COMMA_LOCKVAL_SRC_POS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo AssertMsg(arc == ERROR_INTERRUPT || arc == ERROR_TIMEOUT,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* are there any spawning sessions? */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo // get reference to the machines list in VirtualBox
f0ca1d9a12d54d304791bc74525e2010ca924726sb VirtualBox::MachinesOList &allMachines = that->mVirtualBox->getMachinesList();
c1c61f44e88f4c8c155272ee56d868043146096asb // lock the machines list for reading
c1c61f44e88f4c8c155272ee56d868043146096asb AutoReadLock thatLock(allMachines.getLockHandle() COMMA_LOCKVAL_SRC_POS);
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna /* close the old muxsem */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* obtain a new set of opened machines */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (MachinesOList::iterator it = allMachines.begin();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /// @todo handle situations with more than 64 objects
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo ("maximum of 64 mutex semaphores reached (%d)",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo LogFlowFunc(("UPDATE: direct session count = %d\n", cnt));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* create a new muxsem */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo APIRET arc = ::DosCreateMuxWaitSem(NULL, &muxSem, cnt,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* obtain a new set of spawned machines */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (MachinesOList::iterator it = allMachines.begin();
06db247c678f0e3956535e8a6dec31d6c2108827raghuram LogFlowFunc(("UPDATE: spawned session count = %d\n", cntSpawned));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo while (true);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* close the muxsem */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* release sets of machines if any */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo bool update = false;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo bool updateSpawned = false;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* release the caller to let uninit() ever proceed */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* determine wait timeout adaptively: after updating information
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * relevant to the client watcher, check a few times more
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * frequently. This ensures good reaction time when the signalling
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * has to be done a bit before the actual change for technical
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * reasons, and saves CPU cycles when no activities are expected. */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo } while (!ASMAtomicCmpXchgU8(&that->mUpdateAdaptCtr, uNew, uOld));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo Assert(uOld <= RT_ELEMENTS(s_aUpdateTimeoutSteps) - 1);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Restore the caller before using VirtualBox. If it fails, this
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * means VirtualBox is being uninitialized and we must terminate.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* RT_SUCCESS(rc) means an update event is signaled */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo // get reference to the machines list in VirtualBox
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo VirtualBox::MachinesOList &allMachines = that->mVirtualBox->getMachinesList();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo // lock the machines list for reading
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo AutoReadLock thatLock(allMachines.getLockHandle() COMMA_LOCKVAL_SRC_POS);
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /* obtain a new set of opened machines */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG for (MachinesOList::iterator it = allMachines.begin();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo LogFlowFunc(("UPDATE: direct session count = %d\n", cnt));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* obtain a new set of spawned machines */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (MachinesOList::iterator it = allMachines.begin();
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna LogFlowFunc(("UPDATE: spawned session count = %d\n", cntSpawned));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng // machines lock unwinds here
19b65a69adc64b3289ccb2fc32b805782e3f4540sb updateSpawned |= (spawnedMachines[i])->checkForSpawnFailure();
19b65a69adc64b3289ccb2fc32b805782e3f4540sb /* reap child processes */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo VirtualBox::ClientWatcher::ProcessList::iterator it = that->mProcesses.begin();
205eeb1ae627fcf67b5705c443a2b56a8263406blm int vrc = ::RTProcWait(pid, RTPROCWAIT_FLAGS_NOBLOCK, &status);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo LogRel(("Reaper: Pid %d (%x) exited normally: %d (%#x)\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo LogRel(("Reaper: Pid %d (%x) was signalled: %d (%#x)\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo LogFlowFunc(("pid %d (%x) was reaped, status=%d, reason=%d\n",
34b64c01c6a2242177691e1420a386e2789f79dcWENTAO YANG LogFlowFunc(("pid %d (%x) was NOT reaped, vrc=%Rrc\n",
34b64c01c6a2242177691e1420a386e2789f79dcWENTAO YANG /* remove the process if it is not already running */
7a327842c3ad1ec3b602c454b218df4ebbc716fbwentaoy while (true);
7a327842c3ad1ec3b602c454b218df4ebbc716fbwentaoy /* release sets of machines if any */
808f26a819b6259a3340d8d53074a2f1635315cbSriharsha Basavapatna#elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER)
19b65a69adc64b3289ccb2fc32b805782e3f4540sb bool updateSpawned = false;
808f26a819b6259a3340d8d53074a2f1635315cbSriharsha Basavapatna AutoCaller autoCaller(that->mVirtualBox);
19b65a69adc64b3289ccb2fc32b805782e3f4540sb /* release the caller to let uninit() ever proceed */
19b65a69adc64b3289ccb2fc32b805782e3f4540sb /* determine wait timeout adaptively: after updating information
19b65a69adc64b3289ccb2fc32b805782e3f4540sb * relevant to the client watcher, check a few times more
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * frequently. This ensures good reaction time when the signalling
34683adecebe88ca2c857e28be4749f3a083f9fcsg * has to be done a bit before the actual change for technical
34683adecebe88ca2c857e28be4749f3a083f9fcsg * reasons, and saves CPU cycles when no activities are expected. */
34683adecebe88ca2c857e28be4749f3a083f9fcsg } while (!ASMAtomicCmpXchgU8(&that->mUpdateAdaptCtr, uNew, uOld));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo Assert(uOld <= RT_ELEMENTS(s_aUpdateTimeoutSteps) - 1);
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * Restore the caller before using VirtualBox. If it fails, this
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * means VirtualBox is being uninitialized and we must terminate.
19b65a69adc64b3289ccb2fc32b805782e3f4540sb /** @todo this quite big effort for catching machines in spawning
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * state which can't be caught by the token mechanism (as the token
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * can't be in the other process yet) could be eliminated if the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * reaping is made smarter, having cross-reference information
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * from the pid to the corresponding machine object. Both cases do
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * more or less the same thing anyway. */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* RT_SUCCESS(rc) means an update event is signaled */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo // get reference to the machines list in VirtualBox
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo VirtualBox::MachinesOList &allMachines = that->mVirtualBox->getMachinesList();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo // lock the machines list for reading
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo AutoReadLock thatLock(allMachines.getLockHandle() COMMA_LOCKVAL_SRC_POS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* obtain a new set of spawned machines */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (MachinesOList::iterator it = allMachines.begin();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo LogFlowFunc(("UPDATE: spawned session count = %d\n", cntSpawned));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo // machines lock unwinds here
19b65a69adc64b3289ccb2fc32b805782e3f4540sb updateSpawned |= (spawnedMachines[i])->checkForSpawnFailure();
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* reap child processes */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG AutoWriteLock alock(that->mLock COMMA_LOCKVAL_SRC_POS);
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG LogFlowFunc(("UPDATE: child process count = %d\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo VirtualBox::ClientWatcher::ProcessList::iterator it = that->mProcesses.begin();
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG int vrc = ::RTProcWait(pid, RTPROCWAIT_FLAGS_NOBLOCK, &status);
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG if ( status.enmReason != RTPROCEXITREASON_NORMAL
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG LogRel(("Reaper: Pid %d (%x) exited normally: %d (%#x)\n",
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG LogRel(("Reaper: Pid %d (%x) abended: %d (%#x)\n",
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG LogRel(("Reaper: Pid %d (%x) was signalled: %d (%#x)\n",
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG LogFlowFunc(("pid %d (%x) was reaped, status=%d, reason=%d\n",
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG LogFlowFunc(("pid %d (%x) was NOT reaped, vrc=%Rrc\n",
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /* remove the process if it is not already running */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo while (true);
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /* release sets of machines if any */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG/* vi: set tabstop=4 shiftwidth=4 expandtab: */