- Timestamp:
- Oct 20, 2008 7:49:09 PM (16 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/MachineImpl.cpp
r13372 r13405 3114 3114 3115 3115 /** 3116 * Called from the client watcher thread to check for unexpected client 3117 * process death during Session_Spawning state. 3118 * 3119 * @note On Win32 and on OS/2, this method is called only when we've got the 3120 * mutex (i.e. the client has either died or terminated normally). This 3121 * method always returns true. 3122 * 3123 * @note On Linux, the method returns true if the client process has 3124 * terminated abnormally (and/or the session has been uninitialized) and 3125 * false if it is still alive. 3126 * 3127 * @note Locks this object for writing. 3128 */ 3129 bool Machine::checkForSpawnFailure() 3130 { 3131 AutoCaller autoCaller (this); 3132 if (!autoCaller.isOk()) 3133 { 3134 /* nothing to do */ 3135 LogFlowThisFunc (("Already uninitialized!")); 3136 return true; 3137 } 3138 3139 /* VirtualBox::addProcessToReap() needs a write lock */ 3140 AutoMultiWriteLock2 alock (mParent, this); 3141 3142 if (mData->mSession.mState != SessionState_Spawning) 3143 { 3144 /* nothing to do */ 3145 LogFlowThisFunc (("Not spawning any more!")); 3146 return true; 3147 } 3148 3149 HRESULT rc = S_OK; 3150 3151 RTPROCSTATUS status; 3152 int vrc = ::RTProcWait (mData->mSession.mPid, RTPROCWAIT_FLAGS_NOBLOCK, 3153 &status); 3154 3155 if (vrc != VERR_PROCESS_RUNNING) 3156 rc = setError (E_FAIL, 3157 tr ("The virtual machine '%ls' terminated unexpectedly during startup"), 3158 name().raw()); 3159 3160 if (FAILED (rc)) 3161 { 3162 /* Remove the remote control from the list on failure 3163 * and reset session state to Closed. */ 3164 mData->mSession.mRemoteControls.clear(); 3165 mData->mSession.mState = SessionState_Closed; 3166 3167 /* finalize the progress after setting the state, for consistency */ 3168 mData->mSession.mProgress->notifyComplete (rc); 3169 mData->mSession.mProgress.setNull(); 3170 3171 mParent->addProcessToReap (mData->mSession.mPid); 3172 mData->mSession.mPid = NIL_RTPROCESS; 3173 3174 mParent->onSessionStateChange (mData->mUuid, SessionState_Closed); 3175 return true; 3176 } 3177 3178 return false; 3179 } 3180 3181 /** 3116 3182 * Saves the registry entry of this machine to the given configuration node. 3117 3183 * -
trunk/src/VBox/Main/VirtualBoxImpl.cpp
r12284 r13405 2138 2138 progress.queryInterfaceTo (aProgress); 2139 2139 2140 /* signal the client watcher thread */ 2141 updateClientWatcher(); 2142 2140 2143 /* fire an event */ 2141 2144 onSessionStateChange (aMachineId, SessionState_Spawning); … … 2932 2935 2933 2936 aVector = SessionMachineVector (list.begin(), list.end()); 2937 return; 2938 } 2939 2940 /** 2941 * Returns the list of opened machines (i.e. machines having direct sessions 2942 * opened by client processes). 2943 * 2944 * @note the returned list contains smart pointers. So, clear it as soon as 2945 * it becomes no more necessary to release instances. 2946 * @note it can be possible that a session machine from the list has been 2947 * already uninitialized, so a) lock the instance and b) chheck for 2948 * instance->isReady() return value before manipulating the object directly 2949 * (i.e. not through COM methods). 2950 * 2951 * @note Locks objects for reading. 2952 */ 2953 void VirtualBox::getSpawnedMachines (MachineVector &aVector) 2954 { 2955 AutoCaller autoCaller (this); 2956 AssertComRCReturn (autoCaller.rc(), (void) 0); 2957 2958 std::list <ComObjPtr <Machine> > list; 2959 2960 { 2961 AutoReadLock alock (this); 2962 2963 for (MachineList::iterator it = mData.mMachines.begin(); 2964 it != mData.mMachines.end(); 2965 ++ it) 2966 { 2967 ComObjPtr <Machine> m = (*it); 2968 SessionState_T state; 2969 m->COMGETTER(SessionState(&state)); 2970 if (state == SessionState_Spawning) 2971 list.push_back (m); 2972 } 2973 } 2974 2975 aVector = MachineVector (list.begin(), list.end()); 2934 2976 return; 2935 2977 } … … 4637 4679 4638 4680 SessionMachineVector machines; 4681 MachineVector spawnedMachines; 4639 4682 size_t cnt = 0; 4683 size_t cntSpawned = 0; 4640 4684 4641 4685 #if defined(RT_OS_WINDOWS) … … 4705 4749 for (size_t i = 0; i < cnt; ++ i) 4706 4750 handles [i + 1] = (machines [i])->ipcSem(); 4751 4752 #if 0 /* untested */ 4753 /* check for spawn errors */ 4754 that->getSpawnedMachines (spawnedMachines); 4755 cntSpawned = spawnedMachines.size(); 4756 for (size_t i = 0; i < cntSpawned; ++ i) 4757 (spawnedMachines [i])->checkForSpawnFailure(); 4758 #endif 4707 4759 } 4708 4760 } … … 4905 4957 for (size_t i = 0; i < cnt; ++ i) 4906 4958 need_update |= (machines [i])->checkForDeath(); 4959 4960 that->getSpawnedMachines (spawnedMachines); 4961 cntSpawned = spawnedMachines.size(); 4962 4963 for (size_t i = 0; i < cntSpawned; ++ i) 4964 (spawnedMachines [i])->checkForSpawnFailure(); 4907 4965 4908 4966 /* reap child processes */ -
trunk/src/VBox/Main/include/MachineImpl.h
r13356 r13405 552 552 // public methods only for internal purposes 553 553 554 // 555 // Called from the client watcher thread to check for unexpected client 556 // process death during Session_Spawning state. 557 // 558 bool checkForSpawnFailure(); 559 554 560 /// @todo (dmik) add lock and make non-inlined after revising classes 555 561 // that use it. Note: they should enter Machine lock to keep the returned … … 854 860 855 861 bool checkForDeath(); 862 bool checkForSpawnFailure(); 856 863 857 864 #if defined (RT_OS_WINDOWS) -
trunk/src/VBox/Main/include/VirtualBoxImpl.h
r12284 r13405 230 230 231 231 typedef std::vector <ComObjPtr <SessionMachine> > SessionMachineVector; 232 typedef std::vector <ComObjPtr <Machine> > MachineVector; 232 233 void getOpenedMachines (SessionMachineVector &aVector); 234 void getSpawnedMachines (MachineVector &aVector); 233 235 234 236 bool isMachineIdValid (const Guid &aId)
Note:
See TracChangeset
for help on using the changeset viewer.