- Timestamp:
- Nov 12, 2009 5:09:46 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ConsoleImplTeleporter.cpp
r24558 r24614 117 117 PRTTCPSERVER mhServer; 118 118 PRTTIMERLR mphTimerLR; 119 bool mfStartPaused;120 119 bool mfLockedMedia; 121 120 int mRc; … … 129 128 , mhServer(NULL) 130 129 , mphTimerLR(phTimerLR) 131 , mfStartPaused(false)132 130 , mfLockedMedia(false) 133 131 , mRc(VINF_SUCCESS) … … 637 635 638 636 /* 639 * If we're paused, mention this to the target side.640 *641 * Note: This means you have to resume the target manually if you pause it642 * during the teleportation.643 */644 if ( vrc == VINF_SSM_LIVE_SUSPENDED645 || pState->menmOldMachineState == MachineState_Paused)646 {647 hrc = teleporterSrcSubmitCommand(pState, "pause");648 if (FAILED(hrc))649 return hrc;650 }651 652 /*653 637 * We're at the point of no return. 654 638 */ … … 660 644 661 645 /* 662 * The last thing we do is to hand over any media we might have locked. 646 * Hand over any media which we might be sharing. 647 * 648 * Note! This is only important on localhost teleportations. 663 649 */ 664 650 /** @todo Maybe we should only do this if it's a local teleportation... */ … … 672 658 return hrc; 673 659 674 hrc = teleporterSrcSubmitCommand(pState, "done"); 660 /* 661 * The FINAL step is giving the target instructions how to proceed with the VM. 662 */ 663 if ( vrc == VINF_SSM_LIVE_SUSPENDED 664 || pState->menmOldMachineState == MachineState_Paused) 665 hrc = teleporterSrcSubmitCommand(pState, "hand-over-paused"); 666 else 667 hrc = teleporterSrcSubmitCommand(pState, "hand-over-resume"); 675 668 if (FAILED(hrc)) 676 669 return hrc; … … 705 698 if (SUCCEEDED(hrc)) 706 699 hrc = pState->mptrConsole->teleporterSrc(pState); 700 701 /* Close the connection ASAP on so that the other side can complete. */ 702 if (pState->mhSocket != NIL_RTSOCKET) 703 { 704 RTTcpClientClose(pState->mhSocket); 705 pState->mhSocket = NIL_RTSOCKET; 706 } 707 707 708 708 /* Aaarg! setMachineState trashes error info on Windows, so we have to … … 714 714 pState->mptrProgress->setCancelCallback(NULL, NULL); 715 715 716 /* Write lock the console before resetting mptrCancelableProgress and fixing the state. */ 716 /* 717 * Write lock the console before resetting mptrCancelableProgress and 718 * fixing the state. 719 */ 717 720 AutoWriteLock autoLock(pState->mptrConsole); 718 721 pState->mptrConsole->mptrCancelableProgress.setNull(); … … 825 828 * Cleanup. 826 829 */ 827 if (pState->mhSocket != NIL_RTSOCKET) 828 { 829 RTTcpClientClose(pState->mhSocket); 830 pState->mhSocket = NIL_RTSOCKET; 831 } 830 Assert(pState->mhSocket == NIL_RTSOCKET); 832 831 delete pState; 833 832 … … 1020 1019 { 1021 1020 vrc = State.mRc; 1022 if (RT_SUCCESS(vrc))1023 {1024 if (State.mfStartPaused)1025 setMachineState(MachineState_Paused);1026 else1027 vrc = VMR3Resume(pVM);1028 }1029 1021 /* Power off the VM on failure unless the state callback 1030 1022 already did that. */ 1031 else1023 if (RT_FAILURE(vrc)) 1032 1024 { 1033 1025 VMSTATE enmVMState = VMR3GetState(pVM); … … 1103 1095 1104 1096 1105 static int teleporterTcpWriteACK(TeleporterStateTrg *pState )1097 static int teleporterTcpWriteACK(TeleporterStateTrg *pState, bool fAutomaticUnlock = true) 1106 1098 { 1107 1099 int rc = RTTcpWrite(pState->mhSocket, "ACK\n", sizeof("ACK\n") - 1); … … 1109 1101 { 1110 1102 LogRel(("Teleporter: RTTcpWrite(,ACK,) -> %Rrc\n", rc)); 1111 teleporterTrgUnlockMedia(pState); 1103 if (fAutomaticUnlock) 1104 teleporterTrgUnlockMedia(pState); 1112 1105 } 1113 1106 RTTcpFlush(pState->mhSocket); … … 1237 1230 vrc = VERR_SSM_CANCELLED; 1238 1231 } 1239 else if (!strcmp(szCmd, "pause"))1240 {1241 pState->mfStartPaused = true;1242 vrc = teleporterTcpWriteACK(pState);1243 }1244 1232 else if (!strcmp(szCmd, "lock-media")) 1245 1233 { … … 1256 1244 } 1257 1245 } 1258 else if (!strcmp(szCmd, "done")) 1246 else if ( !strcmp(szCmd, "hand-over-resume") 1247 || !strcmp(szCmd, "hand-over-paused")) 1259 1248 { 1260 1249 /* 1261 * The ACK is the point of no return. 1250 * Point of no return. 1251 * 1252 * Note! Since we cannot tell whether a VMR3Resume failure is 1253 * destructive for the source or not, we have little choice 1254 * but to ACK it first and take any failures locally. 1255 * 1256 * Ideally, we should try resume it first and then ACK (or 1257 * NACK) the request since this would reduce latency and 1258 * make it possible to recover from some VMR3Resume failures. 1262 1259 */ 1263 1260 if ( pState->mptrProgress->notifyPointOfNoReturn() 1264 1261 && pState->mfLockedMedia) 1262 { 1265 1263 vrc = teleporterTcpWriteACK(pState); 1264 if (RT_SUCCESS(vrc)) 1265 { 1266 if (!strcmp(szCmd, "hand-over-resume")) 1267 vrc = VMR3Resume(pState->mpVM); 1268 else 1269 pState->mptrConsole->setMachineState(MachineState_Paused); 1270 fDone = true; 1271 break; 1272 } 1273 } 1266 1274 else 1267 1275 { … … 1269 1277 teleporterTcpWriteNACK(pState, vrc); 1270 1278 } 1271 fDone = true;1272 break;1273 1279 } 1274 1280 else
Note:
See TracChangeset
for help on using the changeset viewer.