- Timestamp:
- Sep 11, 2013 2:08:36 PM (11 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/Makefile.kmk
r48406 r48431 50 50 $(error "VBox: VBOX_WITH_XPCOM isn't defined") 51 51 endif 52 ifneq ($(KBUILD_TARGET),os2) 53 VBOX_MAIN_DEFS += VBOX_WITH_SYS_V_IPC_SESSION_WATCHER 54 endif 52 VBOX_MAIN_DEFS += VBOX_WITH_GENERIC_SESSION_WATCHER 55 53 endif 56 54 VBOX_MAIN_DEFS += \ -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r48406 r48431 17479 17479 <interface 17480 17480 name="IInternalSessionControl" extends="$unknown" 17481 uuid=" 41506410-03d3-4b0c-9b27-e8e5149ce775"17481 uuid="2d2124a7-0f62-4907-ae21-eee5a559bdde" 17482 17482 internal="yes" 17483 17483 wsmap="suppress" … … 17541 17541 <param name="machine" type="IMachine" dir="in"/> 17542 17542 <param name="lockType" type="LockType" dir="in"/> 17543 <param name="token Id" type="wstring" dir="in"/>17543 <param name="token" type="IToken" dir="in"/> 17544 17544 </method> 17545 17545 </if> -
trunk/src/VBox/Main/include/ClientToken.h
r47561 r48431 3 3 /** @file 4 4 * 5 * VirtualBox API client token abstraction5 * VirtualBox API client session token abstraction 6 6 */ 7 7 … … 25 25 26 26 #include "MachineImpl.h" 27 #ifdef VBOX_WITH_GENERIC_SESSION_WATCHER 28 # include "TokenImpl.h" 29 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 27 30 28 31 #if defined(RT_OS_WINDOWS) … … 35 38 # define CTTOKENARG -1 36 39 # define CTTOKENTYPE int 40 #elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 41 # define CTTOKENARG NULL 42 # define CTTOKENTYPE MachineToken * 37 43 #else 38 44 # error "Port me!" … … 49 55 * Constructor which creates a usable instance 50 56 * 51 * @param pMachine Reference to Machine object 57 * @param pMachine Reference to Machine object 58 * @param pSessionMachine Reference to corresponding SessionMachine object 52 59 */ 53 ClientToken(const ComObjPtr<Machine> &pMachine );60 ClientToken(const ComObjPtr<Machine> &pMachine, SessionMachine *pSessionMachine); 54 61 55 62 /** … … 74 81 CTTOKENTYPE getToken(); 75 82 83 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 76 84 /** 77 85 * Release token now. Returns information if the client has terminated. 78 86 */ 79 87 bool release(); 88 #endif /* !VBOX_WITH_GENERIC_SESSION_WATCHER */ 80 89 81 90 private: … … 88 97 CTTOKENTYPE mClientToken; 89 98 Utf8Str mClientTokenId; 99 #ifdef VBOX_WITH_GENERIC_SESSION_WATCHER 100 bool mClientTokenPassed; 101 #endif 90 102 }; 91 103 -
trunk/src/VBox/Main/include/ClientTokenHolder.h
r47561 r48431 3 3 /** @file 4 4 * 5 * VirtualBox API client token holder (in the client process)5 * VirtualBox API client session token holder (in the client process) 6 6 */ 7 7 … … 35 35 # define CTHSEMARG -1 36 36 # define CTHSEMTYPE int 37 #elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 38 /* the token object based implementation needs no semaphores */ 37 39 #else 38 40 # error "Port me!" … … 46 48 { 47 49 public: 50 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 48 51 /** 49 52 * Constructor which creates a usable instance … … 52 55 */ 53 56 ClientTokenHolder(const Utf8Str &strTokenId); 57 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 58 /** 59 * Constructor which creates a usable instance 60 * 61 * @param aToken Reference to token object 62 */ 63 ClientTokenHolder(IToken *aToken); 64 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 54 65 55 66 /** … … 69 80 ClientTokenHolder(); 70 81 82 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 71 83 Utf8Str mClientTokenId; 84 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 85 ComPtr<IToken> mToken; 86 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 87 #ifdef CTHSEMTYPE 72 88 CTHSEMTYPE mSem; 89 #endif 90 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 73 91 RTTHREAD mThread; 92 #endif 74 93 #ifdef RT_OS_WINDOWS 75 94 CTHTHREADSEMTYPE mThreadSem; -
trunk/src/VBox/Main/include/ClientWatcher.h
r47561 r48431 3 3 /** @file 4 4 * 5 * VirtualBox API client watcher5 * VirtualBox API client session watcher 6 6 */ 7 7 … … 33 33 # define CWUPDATEREQARG NIL_RTSEMEVENT 34 34 # define CWUPDATEREQTYPE RTSEMEVENT 35 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) 36 # define CWUPDATEREQARG 35 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) || defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 36 # define CWUPDATEREQARG NIL_RTSEMEVENT 37 37 # define CWUPDATEREQTYPE RTSEMEVENT 38 38 #else … … 80 80 ProcessList mProcesses; 81 81 82 #if def VBOX_WITH_SYS_V_IPC_SESSION_WATCHER82 #if defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) || defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 83 83 uint8_t mUpdateAdaptCtr; 84 84 #endif -
trunk/src/VBox/Main/include/MachineImpl.h
r48406 r48431 788 788 { return isSessionOpen(aMachine, aControl, true /* aAllowClosing */); } 789 789 790 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 790 791 bool checkForSpawnFailure(); 792 #endif /* !VBOX_WITH_GENERIC_SESSION_WATCHER */ 791 793 792 794 HRESULT prepareRegister(); … … 1034 1036 void FinalRelease(); 1035 1037 1038 struct Uninit 1039 { 1040 enum Reason { Unexpected, Abnormal, Normal }; 1041 }; 1042 1036 1043 // public initializer/uninitializer for internal purposes only 1037 1044 HRESULT init(Machine *aMachine); 1038 1045 void uninit() { uninit(Uninit::Unexpected); } 1046 void uninit(Uninit::Reason aReason); 1047 1039 1048 1040 1049 // util::Lockable interface … … 1096 1105 } 1097 1106 1107 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 1098 1108 bool checkForDeath(); 1099 1109 1100 1110 void getTokenId(Utf8Str &strTokenId); 1111 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 1112 IToken *getToken(); 1113 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 1101 1114 // getClientToken must be only used by callers who can guarantee that 1102 1115 // the object cannot be deleted in the mean time, i.e. have a caller/lock. … … 1152 1165 }; 1153 1166 1154 struct Uninit1155 {1156 enum Reason { Unexpected, Abnormal, Normal };1157 };1158 1159 1167 struct SnapshotTask; 1160 1168 struct DeleteSnapshotTask; … … 1163 1171 friend struct DeleteSnapshotTask; 1164 1172 friend struct RestoreSnapshotTask; 1165 1166 void uninit(Uninit::Reason aReason);1167 1173 1168 1174 HRESULT endSavingState(HRESULT aRC, const Utf8Str &aErrMsg); -
trunk/src/VBox/Main/include/SessionImpl.h
r48297 r48431 72 72 STDMETHOD(GetPID)(ULONG *aPid); 73 73 STDMETHOD(GetRemoteConsole)(IConsole **aConsole); 74 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 74 75 STDMETHOD(AssignMachine)(IMachine *aMachine, LockType_T aLockType, IN_BSTR aTokenId); 76 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 77 STDMETHOD(AssignMachine)(IMachine *aMachine, LockType_T aLockType, IToken *aToken); 78 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 75 79 STDMETHOD(AssignRemoteMachine)(IMachine *aMachine, IConsole *aConsole); 76 80 STDMETHOD(UpdateMachineState)(MachineState_T aMachineState); -
trunk/src/VBox/Main/include/TokenImpl.h
r48297 r48431 40 40 // public initializer/uninitializer for internal purposes only 41 41 HRESULT init(const ComObjPtr<SessionMachine> &pSessionMachine); 42 void uninit( );42 void uninit(bool fAbandon); 43 43 44 44 private: -
trunk/src/VBox/Main/src-client/ClientTokenHolder.cpp
r47561 r48431 1 1 /** @file 2 2 * 3 * VirtualBox API client token holder (in the client process)3 * VirtualBox API client session token holder (in the client process) 4 4 */ 5 5 … … 101 101 } 102 102 103 #elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 104 105 if (!mToken.isNull()) 106 { 107 mToken->Abandon(); 108 mToken.setNull(); 109 } 110 103 111 #else 104 112 # error "Port me!" … … 106 114 } 107 115 116 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 108 117 Session::ClientTokenHolder::ClientTokenHolder(const Utf8Str &strTokenId) : 109 118 mClientTokenId(strTokenId) 110 { 119 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 120 Session::ClientTokenHolder::ClientTokenHolder(IToken *aToken) : 121 mToken(aToken) 122 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 123 { 124 #ifdef CTHSEMTYPE 111 125 mSem = CTHSEMARG; 126 #endif 127 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 112 128 mThread = NIL_RTTHREAD; 129 #endif 113 130 114 131 #if defined(RT_OS_WINDOWS) … … 200 217 mSem = s; 201 218 219 #elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 220 221 /* nothing to do */ 222 202 223 #else 203 224 # error "Port me!" … … 207 228 bool Session::ClientTokenHolder::isReady() 208 229 { 230 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 209 231 return mSem != CTHSEMARG; 232 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 233 return !mToken.isNull(); 234 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 210 235 } 211 236 -
trunk/src/VBox/Main/src-client/SessionImpl.cpp
r48299 r48431 294 294 } 295 295 296 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 296 297 STDMETHODIMP Session::AssignMachine(IMachine *aMachine, LockType_T aLockType, 297 298 IN_BSTR aTokenId) 299 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 300 STDMETHODIMP Session::AssignMachine(IMachine *aMachine, LockType_T aLockType, 301 IToken *aToken) 302 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 298 303 { 299 304 LogFlowThisFuncEnter(); … … 338 343 #endif 339 344 345 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 340 346 Utf8Str strTokenId(aTokenId); 341 347 Assert(!strTokenId.isEmpty()); 348 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 349 AssertPtr(aToken); 350 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 342 351 /* create the machine client token */ 343 352 try 344 353 { 354 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 345 355 mClientTokenHolder = new ClientTokenHolder(strTokenId); 356 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 357 mClientTokenHolder = new ClientTokenHolder(aToken); 358 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 346 359 if (!mClientTokenHolder->isReady()) 347 360 { -
trunk/src/VBox/Main/src-server/ClientToken.cpp
r47561 r48431 1 1 /** @file 2 2 * 3 * VirtualBox API client crash token handling3 * VirtualBox API client session crash token handling 4 4 */ 5 5 … … 58 58 mClientTokenId = "0"; 59 59 # endif /* VBOX_WITH_NEW_SYS_V_KEYGEN */ 60 #elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 61 /* release the token, uses reference counting */ 62 if (mClientToken) 63 { 64 if (!mClientTokenPassed) 65 mClientToken->Release(); 66 mClientToken = NULL; 67 } 60 68 #else 61 69 # error "Port me!" … … 64 72 } 65 73 66 Machine::ClientToken::ClientToken(const ComObjPtr<Machine> &pMachine) : 74 Machine::ClientToken::ClientToken(const ComObjPtr<Machine> &pMachine, 75 SessionMachine *pSessionMachine) : 67 76 mMachine(pMachine) 68 77 { 69 78 #if defined(RT_OS_WINDOWS) 79 NOREF(pSessionMachine); 70 80 Bstr tokenId = pMachine->mData->m_strConfigFileFull; 71 81 for (size_t i = 0; i < tokenId.length(); i++) … … 78 88 mClientTokenId.c_str(), ::GetLastError())); 79 89 #elif defined(RT_OS_OS2) 90 NOREF(pSessionMachine); 80 91 Utf8Str ipcSem = Utf8StrFmt("\\SEM32\\VBOX\\VM\\{%RTuuid}", 81 92 pMachine->mData->mUuid.raw()); … … 86 97 ipcSem.c_str(), arc)); 87 98 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) 99 NOREF(pSessionMachine); 88 100 # ifdef VBOX_WITH_NEW_SYS_V_KEYGEN 89 101 # if defined(RT_OS_FREEBSD) && (HC_ARCH_BITS == 64) … … 158 170 AssertMsgFailedReturnVoid(("Cannot init token, errno=%d", errnoSave)); 159 171 } 172 #elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 173 ComObjPtr<MachineToken> pToken; 174 HRESULT rc = pToken.createObject(); 175 if (SUCCEEDED(rc)) 176 { 177 rc = pToken->init(pSessionMachine); 178 if (SUCCEEDED(rc)) 179 { 180 mClientToken = pToken; 181 if (mClientToken) 182 { 183 rc = mClientToken->AddRef(); 184 if (FAILED(rc)) 185 mClientToken = NULL; 186 } 187 } 188 } 189 pToken.setNull(); 190 mClientTokenPassed = false; 191 /* mClientTokenId isn't really used */ 192 mClientTokenId = pMachine->mData->m_strConfigFileFull; 193 AssertMsg(mClientToken, 194 ("Cannot create token '%s', rc=%Rhrc", 195 mClientTokenId.c_str(), rc)); 160 196 #else 161 197 # error "Port me!" … … 175 211 CTTOKENTYPE Machine::ClientToken::getToken() 176 212 { 213 #ifdef VBOX_WITH_GENERIC_SESSION_WATCHER 214 mClientTokenPassed = true; 215 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 177 216 return mClientToken; 178 217 } 179 218 219 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 180 220 bool Machine::ClientToken::release() 181 221 { … … 202 242 terminated = true; 203 243 } 244 #elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 245 /** @todo r=klaus never tested, this code is not reached */ 246 AssertMsg(mClientToken, ("token must be created")); 247 /* release the token, uses reference counting */ 248 if (mClientToken) 249 { 250 if (!mClientTokenPassed) 251 mClientToken->Release(); 252 mClientToken = NULL; 253 } 254 terminated = true; 204 255 #else 205 256 # error "Port me!" … … 207 258 return terminated; 208 259 } 260 #endif /* !VBOX_WITH_GENERIC_SESSION_WATCHER */ 209 261 210 262 /* vi: set tabstop=4 shiftwidth=4 expandtab: */ -
trunk/src/VBox/Main/src-server/ClientWatcher.cpp
r48068 r48431 1 1 /** @file 2 2 * 3 * VirtualBox API client crash watcher3 * VirtualBox API client session crash watcher 4 4 */ 5 5 … … 33 33 #include "MachineImpl.h" 34 34 35 #if def VBOX_WITH_SYS_V_IPC_SESSION_WATCHER35 #if defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) || defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 36 36 /** Table for adaptive timeouts. After an update the counter starts at the 37 37 * maximum value and decreases to 0, i.e. first the short timeouts are used … … 66 66 mUpdateReq = NULL; 67 67 } 68 #elif defined(RT_OS_OS2) || defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) 68 #elif defined(RT_OS_OS2) || defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) || defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 69 69 if (mUpdateReq != NIL_RTSEMEVENT) 70 70 { … … 87 87 #elif defined(RT_OS_OS2) 88 88 RTSemEventCreate(&mUpdateReq); 89 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) 89 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) || defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 90 90 RTSemEventCreate(&mUpdateReq); 91 91 /* start with high timeouts, nothing to do */ … … 125 125 /* use short timeouts, as we expect changes */ 126 126 ASMAtomicUoWriteU8(&mUpdateAdaptCtr, RT_ELEMENTS(s_aUpdateTimeoutSteps) - 1); 127 RTSemEventSignal(mUpdateReq); 128 #elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 127 129 RTSemEventSignal(mUpdateReq); 128 130 #else … … 688 690 spawnedMachines.clear(); 689 691 692 #elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER) 693 694 bool update = false; 695 bool updateSpawned = false; 696 697 do 698 { 699 AutoCaller autoCaller(that->mVirtualBox); 700 if (!autoCaller.isOk()) 701 break; 702 703 do 704 { 705 /* release the caller to let uninit() ever proceed */ 706 autoCaller.release(); 707 708 /* determine wait timeout adaptively: after updating information 709 * relevant to the client watcher, check a few times more 710 * frequently. This ensures good reaction time when the signalling 711 * has to be done a bit before the actual change for technical 712 * reasons, and saves CPU cycles when no activities are expected. */ 713 RTMSINTERVAL cMillies; 714 { 715 uint8_t uOld, uNew; 716 do 717 { 718 uOld = ASMAtomicUoReadU8(&that->mUpdateAdaptCtr); 719 uNew = uOld ? uOld - 1 : uOld; 720 } while (!ASMAtomicCmpXchgU8(&that->mUpdateAdaptCtr, uNew, uOld)); 721 Assert(uOld <= RT_ELEMENTS(s_aUpdateTimeoutSteps) - 1); 722 cMillies = s_aUpdateTimeoutSteps[uOld]; 723 } 724 725 int rc = RTSemEventWait(that->mUpdateReq, cMillies); 726 727 /* 728 * Restore the caller before using VirtualBox. If it fails, this 729 * means VirtualBox is being uninitialized and we must terminate. 730 */ 731 autoCaller.add(); 732 if (!autoCaller.isOk()) 733 break; 734 735 if (RT_SUCCESS(rc) || update || updateSpawned) 736 { 737 /* RT_SUCCESS(rc) means an update event is signaled */ 738 739 #if 0 740 // get reference to the machines list in VirtualBox 741 VirtualBox::MachinesOList &allMachines = that->mVirtualBox->getMachinesList(); 742 743 // lock the machines list for reading 744 AutoReadLock thatLock(allMachines.getLockHandle() COMMA_LOCKVAL_SRC_POS); 745 746 if (RT_SUCCESS(rc) || update) 747 { 748 /* obtain a new set of opened machines */ 749 machines.clear(); 750 751 for (MachinesOList::iterator it = allMachines.begin(); 752 it != allMachines.end(); 753 ++it) 754 { 755 ComObjPtr<SessionMachine> sm; 756 if ((*it)->isSessionOpenOrClosing(sm)) 757 machines.push_back(sm); 758 } 759 760 cnt = machines.size(); 761 LogFlowFunc(("UPDATE: direct session count = %d\n", cnt)); 762 } 763 764 if (RT_SUCCESS(rc) || updateSpawned) 765 { 766 /* obtain a new set of spawned machines */ 767 spawnedMachines.clear(); 768 769 for (MachinesOList::iterator it = allMachines.begin(); 770 it != allMachines.end(); 771 ++it) 772 { 773 if ((*it)->isSessionSpawning()) 774 spawnedMachines.push_back(*it); 775 } 776 777 cntSpawned = spawnedMachines.size(); 778 LogFlowFunc(("UPDATE: spawned session count = %d\n", cntSpawned)); 779 } 780 781 // machines lock unwinds here 782 #endif 783 } 784 785 #if 0 786 update = false; 787 for (size_t i = 0; i < cnt; ++i) 788 update |= (machines[i])->checkForDeath(); 789 790 updateSpawned = false; 791 for (size_t i = 0; i < cntSpawned; ++i) 792 updateSpawned |= (spawnedMachines[i])->checkForSpawnFailure(); 793 #endif 794 795 /* reap child processes */ 796 { 797 AutoWriteLock alock(that->mLock COMMA_LOCKVAL_SRC_POS); 798 if (that->mProcesses.size()) 799 { 800 LogFlowFunc(("UPDATE: child process count = %d\n", 801 that->mProcesses.size())); 802 VirtualBox::ClientWatcher::ProcessList::iterator it = that->mProcesses.begin(); 803 while (it != that->mProcesses.end()) 804 { 805 RTPROCESS pid = *it; 806 RTPROCSTATUS status; 807 int vrc = ::RTProcWait(pid, RTPROCWAIT_FLAGS_NOBLOCK, &status); 808 if (vrc == VINF_SUCCESS) 809 { 810 if ( status.enmReason != RTPROCEXITREASON_NORMAL 811 || status.iStatus != RTEXITCODE_SUCCESS) 812 { 813 switch (status.enmReason) 814 { 815 default: 816 case RTPROCEXITREASON_NORMAL: 817 LogRel(("Reaper: Pid %d (%x) exited normally: %d (%#x)\n", 818 pid, pid, status.iStatus, status.iStatus)); 819 break; 820 case RTPROCEXITREASON_ABEND: 821 LogRel(("Reaper: Pid %d (%x) abended: %d (%#x)\n", 822 pid, pid, status.iStatus, status.iStatus)); 823 break; 824 case RTPROCEXITREASON_SIGNAL: 825 LogRel(("Reaper: Pid %d (%x) was signalled: %d (%#x)\n", 826 pid, pid, status.iStatus, status.iStatus)); 827 break; 828 } 829 } 830 else 831 LogFlowFunc(("pid %d (%x) was reaped, status=%d, reason=%d\n", 832 pid, pid, status.iStatus, 833 status.enmReason)); 834 it = that->mProcesses.erase(it); 835 } 836 else 837 { 838 LogFlowFunc(("pid %d (%x) was NOT reaped, vrc=%Rrc\n", 839 pid, pid, vrc)); 840 if (vrc != VERR_PROCESS_RUNNING) 841 { 842 /* remove the process if it is not already running */ 843 it = that->mProcesses.erase(it); 844 } 845 else 846 ++it; 847 } 848 } 849 } 850 } 851 } 852 while (true); 853 } 854 while (0); 855 856 /* release sets of machines if any */ 857 machines.clear(); 858 spawnedMachines.clear(); 859 690 860 #else 691 861 # error "Port me!" -
trunk/src/VBox/Main/src-server/MachineImpl.cpp
r48406 r48431 3617 3617 if (fLaunchingVMProcess) 3618 3618 { 3619 if (mData->mSession.mPID == NIL_RTPROCESS) 3620 { 3621 // two or more clients racing for a lock, the one which set the 3622 // session state to Spawning will win, the others will get an 3623 // error as we can't decide here if waiting a little would help 3624 // (only for shared locks this would avoid an error) 3625 return setError(VBOX_E_INVALID_OBJECT_STATE, 3626 tr("The machine '%s' already has a lock request pending"), 3627 mUserData->s.strName.c_str()); 3628 } 3629 3619 3630 // this machine is awaiting for a spawning session to be opened: 3620 3631 // then the calling process must be the one that got started by … … 3653 3664 mData->mSession.mState = SessionState_Spawning; 3654 3665 3666 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 3655 3667 /* Get the client token ID to be passed to the client process */ 3656 3668 Utf8Str strTokenId; 3657 3669 sessionMachine->getTokenId(strTokenId); 3658 3670 Assert(!strTokenId.isEmpty()); 3671 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 3672 /* Get the client token to be passed to the client process */ 3673 ComPtr<IToken> pToken(sessionMachine->getToken()); 3674 /* The token is now "owned" by pToken, fix refcount */ 3675 if (!pToken.isNull()) 3676 pToken->Release(); 3677 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 3659 3678 3660 3679 /* … … 3671 3690 3672 3691 LogFlowThisFunc(("Calling AssignMachine()...\n")); 3692 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 3673 3693 rc = pSessionControl->AssignMachine(sessionMachine, lockType, Bstr(strTokenId).raw()); 3694 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 3695 rc = pSessionControl->AssignMachine(sessionMachine, lockType, pToken); 3696 /* Now the token is owned by the client process. */ 3697 pToken.setNull(); 3698 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 3674 3699 LogFlowThisFunc(("AssignMachine() returned %08X\n", rc)); 3675 3700 … … 8076 8101 /* inform the session that it will be a remote one */ 8077 8102 LogFlowThisFunc(("Calling AssignMachine (NULL)...\n")); 8103 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 8078 8104 HRESULT rc = aControl->AssignMachine(NULL, LockType_Write, Bstr::Empty.raw()); 8105 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 8106 HRESULT rc = aControl->AssignMachine(NULL, LockType_Write, NULL); 8107 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 8079 8108 LogFlowThisFunc(("AssignMachine (NULL) returned %08X\n", rc)); 8080 8109 … … 8166 8195 } 8167 8196 8197 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 8168 8198 /** 8169 8199 * Called from the client watcher thread to check for unexpected client process … … 8259 8289 return false; 8260 8290 } 8291 #endif /* !VBOX_WITH_GENERIC_SESSION_WATCHER */ 8261 8292 8262 8293 /** … … 12645 12676 try 12646 12677 { 12647 mClientToken = new ClientToken(aMachine );12678 mClientToken = new ClientToken(aMachine, this); 12648 12679 if (!mClientToken->isReady()) 12649 12680 { … … 12744 12775 /** 12745 12776 * Uninitializes this session object. If the reason is other than 12746 * Uninit::Unexpected, then this method MUST be called from #checkForDeath(). 12777 * Uninit::Unexpected, then this method MUST be called from #checkForDeath() 12778 * or the client watcher code. 12747 12779 * 12748 12780 * @param aReason uninitialization reason … … 12991 13023 multilock.release(); 12992 13024 12993 RTThreadSleep(500);12994 mParent->AddRef();12995 LONG c = mParent->Release();12996 LogFlowThisFunc(("vbox ref=%d\n", c)); NOREF(c);12997 13025 unconst(mParent) = NULL; 12998 13026 unconst(mPeer) = NULL; … … 13838 13866 ///////////////////////////////////////////////////////////////////////////// 13839 13867 13868 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER 13840 13869 /** 13841 13870 * Called from the client watcher thread to check for expected or unexpected … … 13906 13935 mClientToken->getId(strTokenId); 13907 13936 } 13937 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 13938 IToken *SessionMachine::getToken() 13939 { 13940 LogFlowThisFunc(("\n")); 13941 13942 AutoCaller autoCaller(this); 13943 AssertComRCReturn(autoCaller.rc(), NULL); 13944 13945 Assert(mClientToken); 13946 if (mClientToken) 13947 return mClientToken->getToken(); 13948 else 13949 return NULL; 13950 } 13951 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ 13908 13952 13909 13953 Machine::ClientToken *SessionMachine::getClientToken() -
trunk/src/VBox/Main/src-server/TokenImpl.cpp
r48305 r48431 35 35 void MachineToken::FinalRelease() 36 36 { 37 uninit( );37 uninit(false); 38 38 39 39 BaseFinalRelease(); … … 70 70 * Called either from FinalRelease() or by the parent when it gets destroyed. 71 71 */ 72 void MachineToken::uninit( )72 void MachineToken::uninit(bool fAbandon) 73 73 { 74 74 LogFlowThisFunc(("\n")); … … 82 82 if (!m.pSessionMachine.isNull()) 83 83 { 84 m.pSessionMachine->uninit( );84 m.pSessionMachine->uninit(fAbandon ? SessionMachine::Uninit::Normal : SessionMachine::Uninit::Abnormal); 85 85 m.pSessionMachine.setNull(); 86 86 } … … 96 96 97 97 /* uninit does everything we need */ 98 uninit( );98 uninit(true); 99 99 return S_OK; 100 100 }
Note:
See TracChangeset
for help on using the changeset viewer.