- Timestamp:
- Oct 16, 2009 3:50:35 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 53583
- Location:
- trunk/src/VBox/Main
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ConsoleImpl.cpp
r23810 r23827 6762 6762 } 6763 6763 else if (task->mTeleporterEnabled) 6764 {6765 6764 /* -> ConsoleImplTeleporter.cpp */ 6766 6765 vrc = console->teleporterTrg(pVM, pMachine, task->mStartPaused, task->mProgress); 6767 if (RT_FAILURE(vrc))6768 VMR3PowerOff(pVM);6769 }6770 6766 else if (task->mStartPaused) 6771 6767 /* done */ -
trunk/src/VBox/Main/ConsoleImplTeleporter.cpp
r23810 r23827 240 240 * @param pState The teleporter source state. 241 241 * @param pszCommand The command. 242 * @param fWaitForAck Whether to wait for the ACK. 242 243 * 243 244 * @remarks the setError laziness forces this to be a Console member. 244 245 */ 245 246 HRESULT 246 Console::teleporterSrcSubmitCommand(TeleporterStateSrc *pState, const char *pszCommand )247 Console::teleporterSrcSubmitCommand(TeleporterStateSrc *pState, const char *pszCommand, bool fWaitForAck /*= true*/) 247 248 { 248 249 size_t cchCommand = strlen(pszCommand); … … 254 255 if (RT_FAILURE(vrc)) 255 256 return setError(E_FAIL, tr("Failed writing command '%s': %Rrc"), pszCommand, vrc); 257 if (!fWaitForAck) 258 return S_OK; 256 259 return teleporterSrcReadACK(pState, pszCommand); 257 260 } … … 521 524 { 522 525 /* check if the failure was caused by cancellation. */ 523 BOOL fCancel ed;524 hrc = pState->mptrProgress->COMGETTER(Canceled)(&fCancel ed);525 if (SUCCEEDED(hrc) && fCancel ed)526 BOOL fCancelled; 527 hrc = pState->mptrProgress->COMGETTER(Canceled)(&fCancelled); 528 if (SUCCEEDED(hrc) && fCancelled) 526 529 { 527 530 SSMR3Cancel(pState->mpVM); … … 562 565 { AutoWriteLock autoLock(); } 563 566 564 BOOL fCancel ed = TRUE;565 HRESULT hrc = pState->mptrProgress->COMGETTER(Canceled)(&fCancel ed);567 BOOL fCancelled = TRUE; 568 HRESULT hrc = pState->mptrProgress->COMGETTER(Canceled)(&fCancelled); 566 569 if (FAILED(hrc)) 567 570 return hrc; 568 if (fCancel ed)569 return setError(E_FAIL, tr("cancel ed"));571 if (fCancelled) 572 return setError(E_FAIL, tr("cancelled")); 570 573 571 574 /* … … 624 627 * State fun? Automatic power off? 625 628 */ 629 if (!pState->mptrProgress->notifyPointOfNoReturn()) 630 { 631 teleporterSrcSubmitCommand(pState, "cancel", false /*fWaitForAck*/); 632 return E_FAIL; 633 } 626 634 hrc = teleporterSrcSubmitCommand(pState, "done"); 627 635 if (FAILED(hrc)) … … 650 658 hrc = pState->mptrConsole->teleporterSrc(pState); 651 659 660 /* (Ignore the return here as teleporterSrc deals with cancellation.) */ 652 661 pState->mptrProgress->notifyComplete(hrc); 653 662 pState->mptrProgress->setCancelCallback(NULL, NULL); 663 664 /* 665 * Deal with the state machinery after taking the console object lock. 666 */ 654 667 AutoWriteLock autoLock(pState->mptrConsole); 655 668 if (pState->mptrConsole->mMachineState == MachineState_Saving) … … 695 708 } 696 709 710 /* 711 * Cleanup. 712 */ 697 713 if (pState->mhSocket != NIL_RTSOCKET) 698 714 { … … 700 716 pState->mhSocket = NIL_RTSOCKET; 701 717 } 702 703 pState->mptrProgress->setCancelCallback(NULL, NULL);704 718 delete pState; 705 719 706 return VINF_SUCCESS; 720 return VINF_SUCCESS; /* ignored */ 707 721 } 708 722 … … 847 861 if (RT_SUCCESS(vrc)) 848 862 { 849 HRESULThrc = pMachine->COMSETTER(TeleporterPort)(uPort);863 hrc = pMachine->COMSETTER(TeleporterPort)(uPort); 850 864 if (FAILED(hrc)) 851 865 { … … 876 890 877 891 void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(&State)); 878 pProgress->setCancelCallback(teleporterProgressCancelCallback, pvUser); 879 880 vrc = RTTcpServerListen(hServer, Console::teleporterTrgServeConnection, &State); 881 if (vrc == VERR_TCP_SERVER_STOP) 882 vrc = State.mRc; 883 if (RT_SUCCESS(vrc)) 892 if (pProgress->setCancelCallback(teleporterProgressCancelCallback, pvUser)) 884 893 { 885 if (fStartPaused) 886 setMachineState(MachineState_Paused); 894 vrc = RTTcpServerListen(hServer, Console::teleporterTrgServeConnection, &State); 895 pProgress->setCancelCallback(NULL, NULL); 896 897 bool fPowerOff = false; 898 if (vrc == VERR_TCP_SERVER_STOP) 899 { 900 vrc = State.mRc; 901 if (RT_SUCCESS(vrc)) 902 { 903 if (fStartPaused) 904 setMachineState(MachineState_Paused); 905 else 906 vrc = VMR3Resume(pVM); 907 } 908 /* Power off the VM on failure unless the state callback 909 already did that. */ 910 else 911 { 912 VMSTATE enmVMState = VMR3GetState(pVM); 913 if ( enmVMState != VMSTATE_OFF 914 && enmVMState != VMSTATE_POWERING_OFF) 915 fPowerOff = true; 916 } 917 } 918 else if (vrc == VERR_TCP_SERVER_SHUTDOWN) 919 { 920 /** @todo this crap isn't work right wrt error info. Aaaarrrg! */ 921 BOOL fCancelled = TRUE; 922 hrc = pProgress->COMGETTER(Canceled)(&fCancelled); 923 if (FAILED(hrc) || fCancelled) 924 { 925 setError(E_FAIL, tr("Teleporting canceled")); 926 vrc = VERR_SSM_CANCELLED; 927 } 928 else 929 { 930 setError(E_FAIL, tr("Teleporter timed out waiting for incoming connection")); 931 vrc = VERR_TIMEOUT; 932 } 933 pProgress->setResultCode(E_FAIL); /* ugly! */ 934 LogRel(("Teleporter: RTTcpServerListen aborted - %Rrc\n", vrc)); 935 fPowerOff = true; 936 } 887 937 else 888 vrc = VMR3Resume(pVM); 938 { 939 LogRel(("Teleporter: Unexpected RTTcpServerListen rc: %Rrc\n", vrc)); 940 vrc = VERR_IPE_UNEXPECTED_STATUS; 941 fPowerOff = true; 942 } 943 944 if (fPowerOff) 945 { 946 int vrc2 = VMR3PowerOff(pVM); 947 AssertRC(vrc2); 948 } 889 949 } 890 950 else 891 { 892 LogRel(("Teleporter: RTTcpServerListen -> %Rrc\n", vrc)); 893 } 894 895 pProgress->setCancelCallback(NULL, NULL); 951 vrc = VERR_SSM_CANCELLED; 896 952 } 897 953 … … 935 991 /** 936 992 * @copydoc FNRTTCPSERVE 993 * 994 * @returns VINF_SUCCESS or VERR_TCP_SERVER_STOP. 937 995 */ 938 996 /*static*/ DECLCALLBACK(int) … … 953 1011 954 1012 /* 955 * Password (includes '\n', see teleporterTrg). If it's right, tell 956 * the TCP server to stop listening (frees up host resources and makes sure 957 * this is the last connection attempt). 1013 * Password (includes '\n', see teleporterTrg). 958 1014 */ 959 1015 const char *pszPassword = pState->mstrPassword.c_str(); … … 977 1033 vrc = teleporterTcpWriteACK(pState); 978 1034 if (RT_FAILURE(vrc)) 979 return vrc; 980 1035 return VINF_SUCCESS; 1036 1037 /* 1038 * Stop the server and cancel the timeout timer. 1039 * 1040 * Note! After this point we must return VERR_TCP_SERVER_STOP, while prior 1041 * to it we must not return that value! 1042 */ 981 1043 RTTcpServerShutdown(pState->mhServer); 982 1044 RTTimerLRDestroy(*pState->mphTimerLR); … … 1028 1090 * maybe leave part of these to the saved state machinery? 1029 1091 * Update: We're doing as much as possible in the first SSM pass. */ 1092 else if (!strcmp(szCmd, "cancel")) 1093 { 1094 /* Don't ACK this. */ 1095 LogRel(("Teleporter: Received cancel command.\n")); 1096 vrc = VERR_SSM_CANCELLED; 1097 } 1030 1098 else if (!strcmp(szCmd, "done")) 1031 1099 { 1032 vrc = teleporterTcpWriteACK(pState); 1100 /* 1101 * The ACK is the point of no return. 1102 */ 1103 if (pState->mptrProgress->notifyPointOfNoReturn()) 1104 vrc = teleporterTcpWriteACK(pState); 1105 else 1106 { 1107 vrc = VERR_SSM_CANCELLED; 1108 teleporterTcpWriteNACK(pState, vrc); 1109 } 1033 1110 break; 1034 1111 } -
trunk/src/VBox/Main/ProgressImpl.cpp
r23810 r23827 514 514 515 515 /** 516 * Sets the cancellation callback. 516 * Sets the cancelation callback, checking for cancelation first. 517 * 518 * @returns Success indicator. 519 * @retval true on success. 520 * @retval false if the progress object has already been canceled or is in an 521 * invalid state 517 522 * 518 523 * @param pfnCallback The function to be called upon cancelation. 519 524 * @param pvUser The callback argument. 520 525 */ 521 void ProgressBase::setCancelCallback(void (*pfnCallback)(void *), void *pvUser) 522 { 523 AutoCaller autoCaller(this); 524 AssertComRCReturnVoid(autoCaller.rc()); 525 526 AutoWriteLock alock(this); 526 bool ProgressBase::setCancelCallback(void (*pfnCallback)(void *), void *pvUser) 527 { 528 AutoCaller autoCaller(this); 529 AssertComRCReturn(autoCaller.rc(), false); 530 531 AutoWriteLock alock(this); 532 533 if (mCanceled) 534 return false; 527 535 528 536 m_pvCancelUserArg = pvUser; 529 537 m_pfnCancelCallback = pfnCallback; 530 } 531 538 return true; 539 } 532 540 533 541 //////////////////////////////////////////////////////////////////////////////// … … 1141 1149 } 1142 1150 1151 /** 1152 * Notify the progress object that we're almost at the point of no return. 1153 * 1154 * This atomically checks for and disables cancelation. Calls to 1155 * IProgress::Cancel() made after a successfull call to this method will fail 1156 * and the user can be told. While this isn't entirely clean behavior, it 1157 * prevents issues with an irreversible actually operation succeeding while the 1158 * user belive it was rolled back. 1159 * 1160 * @returns Success indicator. 1161 * @retval true on success. 1162 * @retval false if the progress object has already been canceled or is in an 1163 * invalid state 1164 */ 1165 bool Progress::notifyPointOfNoReturn(void) 1166 { 1167 AutoCaller autoCaller(this); 1168 AssertComRCReturn(autoCaller.rc(), false); 1169 1170 AutoWriteLock alock(this); 1171 1172 if (mCanceled) 1173 return false; 1174 1175 mCancelable = FALSE; 1176 return true; 1177 } 1178 1143 1179 //////////////////////////////////////////////////////////////////////////////// 1144 1180 // CombinedProgress class … … 1591 1627 1592 1628 if (!mCancelable) 1593 return setError (E_FAIL, tr ("Operation cannot be cancel led"));1629 return setError (E_FAIL, tr ("Operation cannot be canceled")); 1594 1630 1595 1631 if (!mCanceled) -
trunk/src/VBox/Main/include/ConsoleImpl.h
r23810 r23827 522 522 HRESULT teleporterSrc(TeleporterStateSrc *pState); 523 523 HRESULT teleporterSrcReadACK(TeleporterStateSrc *pState, const char *pszWhich, const char *pszNAckMsg = NULL); 524 HRESULT teleporterSrcSubmitCommand(TeleporterStateSrc *pState, const char *pszCommand );524 HRESULT teleporterSrcSubmitCommand(TeleporterStateSrc *pState, const char *pszCommand, bool fWaitForAck = true); 525 525 int teleporterTrg(PVM pVM, IMachine *pMachine, bool fStartPaused, Progress *pProgress); 526 526 static DECLCALLBACK(int) teleporterTrgServeConnection(RTSOCKET Sock, void *pvUser); -
trunk/src/VBox/Main/include/ProgressImpl.h
r23810 r23827 86 86 87 87 static HRESULT setErrorInfoOnThread (IProgress *aProgress); 88 voidsetCancelCallback(void (*pfnCallback)(void *), void *pvUser);88 bool setCancelCallback(void (*pfnCallback)(void *), void *pvUser); 89 89 90 90 … … 266 266 const Bstr &aComponent, 267 267 const char *aText, ...); 268 bool notifyPointOfNoReturn(void); 268 269 269 270 /** For com::SupportErrorInfoImpl. */
Note:
See TracChangeset
for help on using the changeset viewer.