Changeset 24298 in vbox
- Timestamp:
- Nov 3, 2009 5:20:02 PM (15 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 4 edited
-
SnapshotImpl.cpp (modified) (23 diffs)
-
VirtualBoxImpl.cpp (modified) (5 diffs)
-
include/MachineImpl.h (modified) (1 diff)
-
include/VirtualBoxImpl.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/SnapshotImpl.cpp
r24291 r24298 1055 1055 //////////////////////////////////////////////////////////////////////////////// 1056 1056 1057 /** Task structure for asynchronous VM operations */ 1058 struct SessionMachine::Task 1059 { 1060 Task (SessionMachine *m, Progress *p) 1061 : machine (m), progress (p) 1062 , state (m->mData->mMachineState) // save the current machine state 1063 , subTask (false) 1057 /** 1058 * Abstract base class for SessionMachine::DeleteSnapshotTask and 1059 * SessionMachine::RestoreSnapshotTask. This is necessary since 1060 * RTThreadCreate cannot call a method as its thread function, so 1061 * instead we have it call the static SessionMachine::taskHandler, 1062 * which can then call the handler() method in here (implemented 1063 * by the children). 1064 */ 1065 struct SessionMachine::SnapshotTask 1066 { 1067 SnapshotTask(SessionMachine *m, 1068 Progress *p, 1069 Snapshot *s) 1070 : pMachine(m), 1071 pProgress(p), 1072 machineStateBackup(m->mData->mMachineState), // save the current machine state 1073 pSnapshot(s) 1064 1074 {} 1065 1075 1066 void modify LastState(MachineState_T s)1067 { 1068 *const_cast <MachineState_T *> (&state) = s;1076 void modifyBackedUpState(MachineState_T s) 1077 { 1078 *const_cast<MachineState_T*>(&machineStateBackup) = s; 1069 1079 } 1070 1080 1071 1081 virtual void handler() = 0; 1072 1082 1073 ComObjPtr<SessionMachine> machine; 1074 ComObjPtr<Progress> progress; 1075 const MachineState_T state; 1076 1077 bool subTask : 1; 1083 ComObjPtr<SessionMachine> pMachine; 1084 ComObjPtr<Progress> pProgress; 1085 const MachineState_T machineStateBackup; 1086 ComObjPtr<Snapshot> pSnapshot; 1078 1087 }; 1079 1088 1080 1089 /** Discard snapshot task */ 1081 1090 struct SessionMachine::DeleteSnapshotTask 1082 : public SessionMachine::Task 1083 { 1084 DeleteSnapshotTask(SessionMachine *m, Progress *p, Snapshot *s) 1085 : Task(m, p), 1086 snapshot(s) 1091 : public SessionMachine::SnapshotTask 1092 { 1093 DeleteSnapshotTask(SessionMachine *m, 1094 Progress *p, 1095 Snapshot *s) 1096 : SnapshotTask(m, p, s) 1087 1097 {} 1088 1098 1089 DeleteSnapshotTask (const Task &task, Snapshot *s) 1090 : Task(task) 1091 , snapshot(s) 1099 void handler() 1100 { 1101 pMachine->deleteSnapshotHandler(*this); 1102 } 1103 1104 private: 1105 DeleteSnapshotTask(const SnapshotTask &task) 1106 : SnapshotTask(task) 1092 1107 {} 1093 1094 void handler()1095 {1096 machine->deleteSnapshotHandler(*this);1097 }1098 1099 ComObjPtr<Snapshot> snapshot;1100 1108 }; 1101 1109 1102 1110 /** Restore snapshot state task */ 1103 1111 struct SessionMachine::RestoreSnapshotTask 1104 : public SessionMachine:: Task1112 : public SessionMachine::SnapshotTask 1105 1113 { 1106 1114 RestoreSnapshotTask(SessionMachine *m, 1107 ComObjPtr<Snapshot> &aSnapshot,1108 1115 Progress *p, 1116 Snapshot *s, 1109 1117 ULONG ulStateFileSizeMB) 1110 : Task(m, p), 1111 m_pSnapshot(aSnapshot), 1118 : SnapshotTask(m, p, s), 1112 1119 m_ulStateFileSizeMB(ulStateFileSizeMB) 1113 1120 {} … … 1115 1122 void handler() 1116 1123 { 1117 machine->restoreSnapshotHandler(*this); 1118 } 1119 1120 ComObjPtr<Snapshot> m_pSnapshot; 1121 ULONG m_ulStateFileSizeMB; 1124 pMachine->restoreSnapshotHandler(*this); 1125 } 1126 1127 ULONG m_ulStateFileSizeMB; 1122 1128 }; 1123 1129 … … 1474 1480 /* create and start the task on a separate thread (note that it will not 1475 1481 * start working until we release alock) */ 1476 RestoreSnapshotTask *task = new RestoreSnapshotTask(this, pSnapshot, progress, ulStateFileSizeMB); 1482 RestoreSnapshotTask *task = new RestoreSnapshotTask(this, 1483 progress, 1484 pSnapshot, 1485 ulStateFileSizeMB); 1477 1486 int vrc = RTThreadCreate(NULL, 1478 1487 taskHandler, … … 1509 1518 1510 1519 /* static */ 1511 DECLCALLBACK(int) SessionMachine::taskHandler (RTTHREAD /* thread */, void *pvUser)1520 DECLCALLBACK(int) SessionMachine::taskHandler(RTTHREAD /* thread */, void *pvUser) 1512 1521 { 1513 1522 AssertReturn(pvUser, VERR_INVALID_POINTER); 1514 1523 1515 Task *task = static_cast <Task *>(pvUser);1524 SnapshotTask *task = static_cast<SnapshotTask*>(pvUser); 1516 1525 task->handler(); 1517 1526 … … 1609 1618 struct MediumDiscardRec 1610 1619 { 1611 MediumDiscardRec() : chain (NULL) {} 1612 1613 MediumDiscardRec (const ComObjPtr<Medium> &aHd, 1614 Medium::MergeChain *aChain = NULL) 1615 : hd (aHd), chain (aChain) {} 1616 1617 MediumDiscardRec (const ComObjPtr<Medium> &aHd, 1618 Medium::MergeChain *aChain, 1619 const ComObjPtr<Medium> &aReplaceHd, 1620 const ComObjPtr<MediumAttachment> &aReplaceHda, 1621 const Guid &aSnapshotId) 1622 : hd (aHd), chain (aChain) 1623 , replaceHd (aReplaceHd), replaceHda (aReplaceHda) 1624 , snapshotId (aSnapshotId) {} 1620 MediumDiscardRec() 1621 : chain(NULL) 1622 {} 1623 1624 MediumDiscardRec(const ComObjPtr<Medium> &aHd, 1625 Medium::MergeChain *aChain = NULL) 1626 : hd(aHd), 1627 chain(aChain) 1628 {} 1629 1630 MediumDiscardRec(const ComObjPtr<Medium> &aHd, 1631 Medium::MergeChain *aChain, 1632 const ComObjPtr<Medium> &aReplaceHd, 1633 const ComObjPtr<MediumAttachment> &aReplaceHda, 1634 const Guid &aSnapshotId) 1635 : hd(aHd), 1636 chain (aChain), 1637 replaceHd(aReplaceHd), 1638 replaceHda(aReplaceHda), 1639 snapshotId(aSnapshotId) 1640 {} 1625 1641 1626 1642 ComObjPtr<Medium> hd; … … 1655 1671 /* we might have been uninitialized because the session was accidentally 1656 1672 * closed by the client, so don't assert */ 1657 aTask.p rogress->notifyComplete(E_FAIL,1658 COM_IIDOF(IMachine),1659 getComponentName(),1660 tr("The session has been accidentally closed"));1673 aTask.pProgress->notifyComplete(E_FAIL, 1674 COM_IIDOF(IMachine), 1675 getComponentName(), 1676 tr("The session has been accidentally closed")); 1661 1677 LogFlowThisFuncLeave(); 1662 1678 return; … … 1666 1682 AutoMultiWriteLock3 alock(this->lockHandle(), 1667 1683 this->snapshotsTreeLockHandle(), 1668 aTask. snapshot->lockHandle());1669 1670 ComPtr<SnapshotMachine> sm = aTask. snapshot->getSnapshotMachine();1684 aTask.pSnapshot->lockHandle()); 1685 1686 ComPtr<SnapshotMachine> sm = aTask.pSnapshot->getSnapshotMachine(); 1671 1687 /* no need to lock the snapshot machine since it is const by definiton */ 1672 1688 … … 1674 1690 1675 1691 /* save the snapshot ID (for callbacks) */ 1676 Guid snapshotId = aTask. snapshot->getId();1692 Guid snapshotId = aTask.pSnapshot->getId(); 1677 1693 1678 1694 MediumDiscardRecList toDiscard; … … 1705 1721 /* skip writethrough hard disks */ 1706 1722 Assert(hd->type() == MediumType_Writethrough); 1707 rc = aTask.p rogress->SetNextOperation(BstrFmt(tr("Skipping writethrough hard disk '%s'"),1708 hd->base()->name().raw()),1709 1); // weight1723 rc = aTask.pProgress->SetNextOperation(BstrFmt(tr("Skipping writethrough hard disk '%s'"), 1724 hd->base()->name().raw()), 1725 1); // weight 1710 1726 CheckComRCThrowRC(rc); 1711 1727 continue; … … 1796 1812 1797 1813 { 1798 ComObjPtr<Snapshot> parentSnapshot = aTask. snapshot->parent();1799 Utf8Str stateFilePath = aTask. snapshot->stateFilePath();1814 ComObjPtr<Snapshot> parentSnapshot = aTask.pSnapshot->parent(); 1815 Utf8Str stateFilePath = aTask.pSnapshot->stateFilePath(); 1800 1816 1801 1817 /* Note that discarding the snapshot will deassociate it from the 1802 1818 * hard disks which will allow the merge+delete operation for them*/ 1803 aTask. snapshot->beginDiscard();1804 aTask. snapshot->uninit();1819 aTask.pSnapshot->beginDiscard(); 1820 aTask.pSnapshot->uninit(); 1805 1821 1806 1822 rc = saveAllSnapshots(); … … 1812 1828 if (!stateFilePath.isEmpty()) 1813 1829 { 1814 aTask.p rogress->SetNextOperation(Bstr(tr("Discarding the execution state")),1815 1); // weight1830 aTask.pProgress->SetNextOperation(Bstr(tr("Discarding the execution state")), 1831 1); // weight 1816 1832 1817 1833 RTFileDelete(stateFilePath.c_str()); … … 1846 1862 it != toDiscard.end();) 1847 1863 { 1848 rc = it->hd->discard (aTask.progress, it->chain);1864 rc = it->hd->discard(aTask.pProgress, it->chain); 1849 1865 CheckComRCBreakRC(rc); 1850 1866 … … 1885 1901 } 1886 1902 1887 if (!aTask.subTask || FAILED(rc)) 1888 { 1889 if (!aTask.subTask) 1890 { 1891 /* saveSettings() below needs a VirtualBox write lock and we need to 1892 * leave this object's lock to do this to follow the {parent-child} 1893 * locking rule. This is the last chance to do that while we are 1894 * still in a protective state which allows us to temporarily leave 1895 * the lock */ 1896 alock.unlock(); 1897 AutoWriteLock vboxLock(mParent); 1898 alock.lock(); 1899 1900 /* preserve existing error info */ 1901 ErrorInfoKeeper eik; 1902 1903 /* restore the machine state */ 1904 setMachineState(aTask.state); 1905 updateMachineStateOnClient(); 1906 1907 if (settingsChanged) 1908 saveSettings(SaveS_InformCallbacksAnyway); 1909 } 1903 if (FAILED(rc)) 1904 { 1905 /* saveSettings() below needs a VirtualBox write lock and we need to 1906 * leave this object's lock to do this to follow the {parent-child} 1907 * locking rule. This is the last chance to do that while we are 1908 * still in a protective state which allows us to temporarily leave 1909 * the lock */ 1910 alock.unlock(); 1911 AutoWriteLock vboxLock(mParent); 1912 alock.lock(); 1913 1914 /* preserve existing error info */ 1915 ErrorInfoKeeper eik; 1916 1917 /* restore the machine state */ 1918 setMachineState(aTask.machineStateBackup); 1919 updateMachineStateOnClient(); 1920 1921 if (settingsChanged) 1922 saveSettings(SaveS_InformCallbacksAnyway); 1910 1923 1911 1924 /* set the result (this will try to fetch current error info on failure) */ 1912 aTask.p rogress->notifyComplete(rc);1925 aTask.pProgress->notifyComplete(rc); 1913 1926 } 1914 1927 1915 1928 if (SUCCEEDED(rc)) 1916 mParent->onSnapshotD iscarded(mData->mUuid, snapshotId);1917 1918 LogFlowThisFunc(("Done d iscarding snapshot (rc=%08X)\n", rc));1929 mParent->onSnapshotDeleted(mData->mUuid, snapshotId); 1930 1931 LogFlowThisFunc(("Done deleting snapshot (rc=%08X)\n", rc)); 1919 1932 LogFlowThisFuncLeave(); 1920 1933 } … … 1937 1950 /* we might have been uninitialized because the session was accidentally 1938 1951 * closed by the client, so don't assert */ 1939 aTask.p rogress->notifyComplete(E_FAIL,1940 COM_IIDOF(IMachine),1941 getComponentName(),1942 tr("The session has been accidentally closed"));1952 aTask.pProgress->notifyComplete(E_FAIL, 1953 COM_IIDOF(IMachine), 1954 getComponentName(), 1955 tr("The session has been accidentally closed")); 1943 1956 1944 1957 LogFlowThisFuncLeave(); … … 1970 1983 /* discard the saved state file if the machine was Saved prior to this 1971 1984 * operation */ 1972 if (aTask. state== MachineState_Saved)1985 if (aTask.machineStateBackup == MachineState_Saved) 1973 1986 { 1974 1987 Assert(!mSSData->mStateFilePath.isEmpty()); 1975 1988 RTFileDelete(mSSData->mStateFilePath.c_str()); 1976 1989 mSSData->mStateFilePath.setNull(); 1977 aTask.modify LastState(MachineState_PoweredOff);1990 aTask.modifyBackedUpState(MachineState_PoweredOff); 1978 1991 rc = saveStateSettings(SaveSTS_StateFilePath); 1979 1992 CheckComRCThrowRC(rc); … … 1984 1997 1985 1998 { 1986 AutoReadLock snapshotLock(aTask. m_pSnapshot);1999 AutoReadLock snapshotLock(aTask.pSnapshot); 1987 2000 1988 2001 /* remember the timestamp of the snapshot we're restoring from */ 1989 snapshotTimeStamp = aTask. m_pSnapshot->getTimeStamp();1990 1991 ComPtr<SnapshotMachine> pSnapshotMachine(aTask. m_pSnapshot->getSnapshotMachine());2002 snapshotTimeStamp = aTask.pSnapshot->getTimeStamp(); 2003 2004 ComPtr<SnapshotMachine> pSnapshotMachine(aTask.pSnapshot->getSnapshotMachine()); 1992 2005 1993 2006 /* copy all hardware data from the snapshot */ … … 2005 2018 2006 2019 rc = createImplicitDiffs(mUserData->mSnapshotFolderFull, 2007 aTask.p rogress,2020 aTask.pProgress, 2008 2021 1, 2009 2022 false /* aOnline */); … … 2022 2035 Assert(mSSData->mStateFilePath.isEmpty()); 2023 2036 2024 if (!aTask. m_pSnapshot->stateFilePath().isEmpty())2037 if (!aTask.pSnapshot->stateFilePath().isEmpty()) 2025 2038 { 2026 Utf8Str snapStateFilePath = aTask. m_pSnapshot->stateFilePath();2039 Utf8Str snapStateFilePath = aTask.pSnapshot->stateFilePath(); 2027 2040 2028 2041 Utf8Str stateFilePath = Utf8StrFmt("%ls%c{%RTuuid}.sav", … … 2034 2047 snapStateFilePath.raw(), stateFilePath.raw())); 2035 2048 2036 aTask.p rogress->SetNextOperation(Bstr(tr("Restoring the execution state")),2037 aTask.m_ulStateFileSizeMB); // weight2049 aTask.pProgress->SetNextOperation(Bstr(tr("Restoring the execution state")), 2050 aTask.m_ulStateFileSizeMB); // weight 2038 2051 2039 2052 /* leave the lock before the potentially lengthy operation */ … … 2046 2059 0, 2047 2060 progressCallback, 2048 aTask.p rogress);2061 aTask.pProgress); 2049 2062 2050 2063 alock.enter(); … … 2061 2074 } 2062 2075 2063 LogFlowThisFunc(("Setting new current snapshot {%RTuuid}\n", aTask. m_pSnapshot->getId().raw()));2076 LogFlowThisFunc(("Setting new current snapshot {%RTuuid}\n", aTask.pSnapshot->getId().raw())); 2064 2077 /* make the snapshot we restored from the current snapshot */ 2065 mData->mCurrentSnapshot = aTask. m_pSnapshot;2078 mData->mCurrentSnapshot = aTask.pSnapshot; 2066 2079 } 2067 2080 … … 2172 2185 { 2173 2186 /* restore the machine state */ 2174 setMachineState(aTask. state);2187 setMachineState(aTask.machineStateBackup); 2175 2188 updateMachineStateOnClient(); 2176 2189 } … … 2178 2191 2179 2192 /* set the result (this will try to fetch current error info on failure) */ 2180 aTask.p rogress->notifyComplete(rc);2193 aTask.pProgress->notifyComplete(rc); 2181 2194 2182 2195 if (SUCCEEDED(rc)) 2183 mParent->onSnapshotD iscarded(mData->mUuid, Guid());2196 mParent->onSnapshotDeleted(mData->mUuid, Guid()); 2184 2197 2185 2198 LogFlowThisFunc(("Done restoring snapshot (rc=%08X)\n", rc)); -
trunk/src/VBox/Main/VirtualBoxImpl.cpp
r24273 r24298 2491 2491 void VirtualBox::onSnapshotTaken (const Guid &aMachineId, const Guid &aSnapshotId) 2492 2492 { 2493 postEvent (new SnapshotEvent(this, aMachineId, aSnapshotId, SnapshotEvent::Taken));2493 postEvent(new SnapshotEvent(this, aMachineId, aSnapshotId, SnapshotEvent::Taken)); 2494 2494 } 2495 2495 … … 2497 2497 * @note Doesn't lock any object. 2498 2498 */ 2499 void VirtualBox::onSnapshotD iscarded(const Guid &aMachineId, const Guid &aSnapshotId)2500 { 2501 postEvent (new SnapshotEvent(this, aMachineId, aSnapshotId, SnapshotEvent::Discarded));2499 void VirtualBox::onSnapshotDeleted(const Guid &aMachineId, const Guid &aSnapshotId) 2500 { 2501 postEvent(new SnapshotEvent(this, aMachineId, aSnapshotId, SnapshotEvent::Discarded)); 2502 2502 } 2503 2503 … … 2505 2505 * @note Doesn't lock any object. 2506 2506 */ 2507 void VirtualBox::onSnapshotChange (const Guid &aMachineId, const Guid &aSnapshotId)2508 { 2509 postEvent (new SnapshotEvent(this, aMachineId, aSnapshotId, SnapshotEvent::Changed));2507 void VirtualBox::onSnapshotChange(const Guid &aMachineId, const Guid &aSnapshotId) 2508 { 2509 postEvent(new SnapshotEvent(this, aMachineId, aSnapshotId, SnapshotEvent::Changed)); 2510 2510 } 2511 2511 … … 2513 2513 struct GuestPropertyEvent : public VirtualBox::CallbackEvent 2514 2514 { 2515 GuestPropertyEvent (VirtualBox *aVBox, const Guid &aMachineId, 2516 IN_BSTR aName, IN_BSTR aValue, IN_BSTR aFlags) 2517 : CallbackEvent (aVBox), machineId (aMachineId) 2518 , name (aName), value (aValue), flags(aFlags) 2519 {} 2520 2521 void handleCallback (const ComPtr<IVirtualBoxCallback> &aCallback) 2522 { 2523 LogFlow (("OnGuestPropertyChange: machineId={%RTuuid}, name='%ls', value='%ls', flags='%ls'\n", 2524 machineId.ptr(), name.raw(), value.raw(), flags.raw())); 2515 GuestPropertyEvent(VirtualBox *aVBox, const Guid &aMachineId, 2516 IN_BSTR aName, IN_BSTR aValue, IN_BSTR aFlags) 2517 : CallbackEvent(aVBox), 2518 machineId(aMachineId), 2519 name(aName), 2520 value(aValue), 2521 flags(aFlags) 2522 {} 2523 2524 void handleCallback(const ComPtr<IVirtualBoxCallback> &aCallback) 2525 { 2526 LogFlow(("OnGuestPropertyChange: machineId={%RTuuid}, name='%ls', value='%ls', flags='%ls'\n", 2527 machineId.ptr(), name.raw(), value.raw(), flags.raw())); 2525 2528 aCallback->OnGuestPropertyChange (machineId.toUtf16(), name, value, flags); 2526 2529 } … … 2533 2536 * @note Doesn't lock any object. 2534 2537 */ 2535 void VirtualBox::onGuestPropertyChange (const Guid &aMachineId, IN_BSTR aName,2536 IN_BSTR aValue, IN_BSTR aFlags)2537 { 2538 postEvent (new GuestPropertyEvent(this, aMachineId, aName, aValue, aFlags));2538 void VirtualBox::onGuestPropertyChange(const Guid &aMachineId, IN_BSTR aName, 2539 IN_BSTR aValue, IN_BSTR aFlags) 2540 { 2541 postEvent(new GuestPropertyEvent(this, aMachineId, aName, aValue, aFlags)); 2539 2542 } 2540 2543 -
trunk/src/VBox/Main/include/MachineImpl.h
r24295 r24298 1034 1034 }; 1035 1035 1036 struct Task;1036 struct SnapshotTask; 1037 1037 struct DeleteSnapshotTask; 1038 1038 struct RestoreSnapshotTask; -
trunk/src/VBox/Main/include/VirtualBoxImpl.h
r24273 r24298 196 196 void updateClientWatcher(); 197 197 198 void onMachineStateChange (const Guid &aId, MachineState_T aState);199 void onMachineDataChange (const Guid &aId);198 void onMachineStateChange(const Guid &aId, MachineState_T aState); 199 void onMachineDataChange(const Guid &aId); 200 200 BOOL onExtraDataCanChange(const Guid &aId, IN_BSTR aKey, IN_BSTR aValue, 201 201 Bstr &aError); 202 202 void onExtraDataChange(const Guid &aId, IN_BSTR aKey, IN_BSTR aValue); 203 void onMachineRegistered (const Guid &aId, BOOL aRegistered);204 void onSessionStateChange (const Guid &aId, SessionState_T aState);205 206 void onSnapshotTaken (const Guid &aMachineId, const Guid &aSnapshotId);207 void onSnapshotD iscarded(const Guid &aMachineId, const Guid &aSnapshotId);208 void onSnapshotChange (const Guid &aMachineId, const Guid &aSnapshotId);209 void onGuestPropertyChange (const Guid &aMachineId, IN_BSTR aName, IN_BSTR aValue,210 IN_BSTR aFlags);203 void onMachineRegistered(const Guid &aId, BOOL aRegistered); 204 void onSessionStateChange(const Guid &aId, SessionState_T aState); 205 206 void onSnapshotTaken(const Guid &aMachineId, const Guid &aSnapshotId); 207 void onSnapshotDeleted(const Guid &aMachineId, const Guid &aSnapshotId); 208 void onSnapshotChange(const Guid &aMachineId, const Guid &aSnapshotId); 209 void onGuestPropertyChange(const Guid &aMachineId, IN_BSTR aName, IN_BSTR aValue, 210 IN_BSTR aFlags); 211 211 212 212 ComObjPtr<GuestOSType> getUnknownOSType();
Note:
See TracChangeset
for help on using the changeset viewer.

