Changeset 46775 in vbox
- Timestamp:
- Jun 25, 2013 12:37:57 PM (11 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 11 edited
-
idl/VirtualBox.xidl (modified) (2 diffs)
-
include/ConsoleImpl.h (modified) (1 diff)
-
include/Global.h (modified) (1 diff)
-
include/HostPower.h (modified) (5 diffs)
-
include/SessionImpl.h (modified) (2 diffs)
-
src-all/Global.cpp (modified) (1 diff)
-
src-client/ConsoleImpl.cpp (modified) (19 diffs)
-
src-client/SessionImpl.cpp (modified) (1 diff)
-
src-server/HostPower.cpp (modified) (9 diffs)
-
src-server/darwin/HostPowerDarwin.cpp (modified) (16 diffs)
-
src-server/win/HostPowerWin.cpp (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/idl/VirtualBox.xidl
r46667 r46775 16847 16847 --> 16848 16848 16849 <enum 16850 name="Reason" 16851 uuid="e7e8e097-299d-4e98-8bbc-c31c2d47d0cc" 16852 > 16853 <desc> 16854 Internal event reason type. 16855 </desc> 16856 16857 <const name="Unspecified" value="0"> 16858 <desc>Null value, means "no known reason".</desc> 16859 </const> 16860 <const name="HostSuspend" value="1"> 16861 <desc>Host is being suspended (power management event).</desc> 16862 </const> 16863 <const name="HostResume" value="2"> 16864 <desc>Host is being resumed (power management event).</desc> 16865 </const> 16866 <const name="HostBatteryLow" value="3"> 16867 <desc>Host is running low on battery (power management event).</desc> 16868 </const> 16869 </enum> 16870 16849 16871 <interface 16850 16872 name="IInternalSessionControl" extends="$unknown" 16851 uuid=" 0ba8d8b3-204b-448e-99c2-242eaa666ea8"16873 uuid="cddf451c-a006-4c33-8245-63b3c9ae6586" 16852 16874 internal="yes" 16853 16875 wsmap="suppress" … … 17345 17367 <param name="enable" type="boolean" dir="in"> 17346 17368 <desc>True enables statistics collection.</desc> 17369 </param> 17370 </method> 17371 17372 <method name="pauseWithReason"> 17373 <desc> 17374 Internal method for triggering a VM pause with a specified reason code. 17375 The reason code can be interpreted by device/drivers and thus it might 17376 behave slightly differently than a normal VM pause. 17377 17378 <result name="VBOX_E_INVALID_VM_STATE"> 17379 Virtual machine not in Running state. 17380 </result> 17381 <result name="VBOX_E_VM_ERROR"> 17382 Virtual machine error in suspend operation. 17383 </result> 17384 <see><link to="Console::pause"/></see> 17385 </desc> 17386 17387 <param name="reason" type="Reason" dir="in"> 17388 <desc>Specify the best matching reason code please.</desc> 17389 </param> 17390 </method> 17391 17392 <method name="resumeWithReason"> 17393 <desc> 17394 Internal method for triggering a VM resume with a specified reason code. 17395 The reason code can be interpreted by device/drivers and thus it might 17396 behave slightly differently than a normal VM resume. 17397 17398 <result name="VBOX_E_INVALID_VM_STATE"> 17399 Virtual machine not in Paused state. 17400 </result> 17401 <result name="VBOX_E_VM_ERROR"> 17402 Virtual machine error in resume operation. 17403 </result> 17404 <see><link to="Console::resume"/></see> 17405 </desc> 17406 17407 <param name="reason" type="Reason" dir="in"> 17408 <desc>Specify the best matching reason code please.</desc> 17409 </param> 17410 </method> 17411 17412 <method name="saveStateWithReason"> 17413 <desc> 17414 Internal method for triggering a VM save state with a specified reason 17415 code. The reason code can be interpreted by device/drivers and thus it 17416 might behave slightly differently than a normal VM save state. 17417 17418 <result name="VBOX_E_INVALID_VM_STATE"> 17419 Virtual machine state neither Running nor Paused. 17420 </result> 17421 <result name="VBOX_E_FILE_ERROR"> 17422 Failed to create directory for saved state file. 17423 </result> 17424 <see><link to="Console::saveState"/></see> 17425 </desc> 17426 17427 <param name="reason" type="Reason" dir="in"> 17428 <desc>Specify the best matching reason code please.</desc> 17429 </param> 17430 <param name="progress" type="IProgress" dir="return"> 17431 <desc>Progress object to track the operation completion.</desc> 17347 17432 </param> 17348 17433 </method> -
trunk/src/VBox/Main/include/ConsoleImpl.h
r46465 r46775 258 258 } 259 259 void enableVMMStatistics(BOOL aEnable); 260 261 HRESULT pause(Reason_T aReason); 262 HRESULT resume(Reason_T aReason); 263 HRESULT saveState(Reason_T aReason, IProgress **aProgress); 260 264 261 265 // callback callers (partly; for some events console callbacks are notified -
trunk/src/VBox/Main/include/Global.h
r39248 r46775 194 194 195 195 /** 196 * Stringify a reason. 197 * 198 * @returns Pointer to a read only string. 199 * @param aReason The reason code. 200 */ 201 static const char *stringifyReason(Reason_T aReason); 202 203 /** 196 204 * Try convert a COM status code to a VirtualBox status code (VBox/err.h). 197 205 * -
trunk/src/VBox/Main/include/HostPower.h
r44528 r46775 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 20 20 21 21 #include "VirtualBoxBase.h" 22 #include "MachineImpl.h"23 22 24 23 #include <vector> … … 29 28 #endif /* RT_OS_DARWIN */ 30 29 31 typedef enum32 {33 HostPowerEvent_Suspend,34 HostPowerEvent_Resume,35 HostPowerEvent_BatteryLow36 } HostPowerEvent;37 38 30 class HostPowerService 39 31 { 40 32 public: 41 33 42 HostPowerService (VirtualBox *aVirtualBox);34 HostPowerService(VirtualBox *aVirtualBox); 43 35 virtual ~HostPowerService(); 44 36 45 void notify (HostPowerEvent aEvent);37 void notify(Reason_T aReason); 46 38 47 39 protected: 48 40 49 VirtualBox *mVirtualBox;41 VirtualBox *mVirtualBox; 50 42 51 std::vector< ComPtr<IConsole> > mConsoles;43 std::vector<ComPtr<IInternalSessionControl> > mSessionControls; 52 44 }; 53 45 … … 65 57 private: 66 58 67 static DECLCALLBACK(int) NotificationThread (RTTHREAD ThreadSelf, void *pInstance);59 static DECLCALLBACK(int) NotificationThread(RTTHREAD ThreadSelf, void *pInstance); 68 60 static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); 69 61 … … 79 71 public: 80 72 81 HostPowerServiceDarwin (VirtualBox *aVirtualBox);73 HostPowerServiceDarwin(VirtualBox *aVirtualBox); 82 74 virtual ~HostPowerServiceDarwin(); 83 75 84 76 private: 85 77 86 static DECLCALLBACK(int) powerChangeNotificationThread (RTTHREAD ThreadSelf, void *pInstance);87 static void powerChangeNotificationHandler (void *pvData, io_service_t service, natural_t messageType, void *pMessageArgument);88 static void lowPowerHandler (void *pvData);78 static DECLCALLBACK(int) powerChangeNotificationThread(RTTHREAD ThreadSelf, void *pInstance); 79 static void powerChangeNotificationHandler(void *pvData, io_service_t service, natural_t messageType, void *pMessageArgument); 80 static void lowPowerHandler(void *pvData); 89 81 90 void checkBatteryCriticalLevel (bool *pfCriticalChanged = NULL);82 void checkBatteryCriticalLevel(bool *pfCriticalChanged = NULL); 91 83 92 84 /* Private member vars */ -
trunk/src/VBox/Main/include/SessionImpl.h
r46465 r46775 5 5 6 6 /* 7 * Copyright (C) 2006-201 2Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 117 117 IProgress *aProgress); 118 118 STDMETHOD(EnableVMMStatistics)(BOOL aEnable); 119 STDMETHOD(PauseWithReason)(Reason_T aReason); 120 STDMETHOD(ResumeWithReason)(Reason_T aReason); 121 STDMETHOD(SaveStateWithReason)(Reason_T aReason, IProgress **aProgress); 119 122 120 123 private: -
trunk/src/VBox/Main/src-all/Global.cpp
r46350 r46775 451 451 } 452 452 453 454 /*static*/ const char * 455 Global::stringifyReason(Reason_T aReason) 456 { 457 switch (aReason) 458 { 459 case Reason_Unspecified: return "unspecified"; 460 case Reason_HostSuspend: return "host suspend"; 461 case Reason_HostResume: return "host resume"; 462 case Reason_HostBatteryLow: return "host battery low"; 463 default: 464 { 465 AssertMsgFailed(("%d (%#x)\n", aReason, aReason)); 466 static char s_szMsg[48]; 467 RTStrPrintf(s_szMsg, sizeof(s_szMsg), "invalid reason %#010x\n", aReason); 468 return s_szMsg; 469 } 470 } 471 } 472 453 473 /*static*/ int 454 474 Global::vboxStatusCodeFromCOM(HRESULT aComStatus) -
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r46610 r46775 263 263 const ComPtr<IProgress> &aServerProgress, 264 264 const Utf8Str &aSavedStateFile, 265 MachineState_T aMachineStateBefore) 265 MachineState_T aMachineStateBefore, 266 Reason_T aReason) 266 267 : VMTask(aConsole, NULL /* aProgress */, aServerProgress, 267 268 true /* aUsesVMPtr */), 268 269 mSavedStateFile(aSavedStateFile), 269 mMachineStateBefore(aMachineStateBefore) 270 mMachineStateBefore(aMachineStateBefore), 271 mReason(aReason) 270 272 {} 271 273 … … 273 275 /* The local machine state we had before. Required if something fails */ 274 276 MachineState_T mMachineStateBefore; 277 /* The reason for saving state */ 278 Reason_T mReason; 275 279 }; 276 280 … … 2074 2078 { 2075 2079 LogFlowThisFuncEnter(); 2076 LogFlowThisFunc(("mMachineState=%d\n", mMachineState));2077 2080 2078 2081 CheckComArgOutPointerValid(aProgress); … … 2083 2086 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2084 2087 2088 LogFlowThisFunc(("mMachineState=%d\n", mMachineState)); 2085 2089 switch (mMachineState) 2086 2090 { … … 2206 2210 { 2207 2211 LogFlowThisFuncEnter(); 2208 LogFlowThisFunc(("mMachineState=%d\n", mMachineState));2209 2212 2210 2213 AutoCaller autoCaller(this); … … 2213 2216 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2214 2217 2218 LogFlowThisFunc(("mMachineState=%d\n", mMachineState)); 2215 2219 if ( mMachineState != MachineState_Running 2216 2220 && mMachineState != MachineState_Teleporting … … 2257 2261 2258 2262 LogFlowThisFuncEnter(); 2259 LogFlowThisFunc(("mMachineState=%d\n", mMachineState));2260 2263 2261 2264 AutoCaller autoCaller(this); … … 2264 2267 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2265 2268 2269 LogFlowThisFunc(("mMachineState=%d\n", mMachineState)); 2266 2270 AssertReturn(m_pVMMDev, E_FAIL); 2267 2271 PPDMIVMMDEVPORT pVmmDevPort = m_pVMMDev->getVMMDevPort(); … … 2401 2405 2402 2406 LogFlowThisFuncEnter(); 2403 LogFlowThisFunc(("mMachineState=%d\n", mMachineState));2404 2407 2405 2408 AutoCaller autoCaller(this); … … 2408 2411 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2409 2412 2413 LogFlowThisFunc(("mMachineState=%d\n", mMachineState)); 2410 2414 if ( mMachineState != MachineState_Running 2411 2415 && mMachineState != MachineState_Teleporting … … 2474 2478 LogFlowThisFuncEnter(); 2475 2479 2476 AutoCaller autoCaller(this); 2477 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 2478 2479 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2480 2481 switch (mMachineState) 2482 { 2483 case MachineState_Running: 2484 case MachineState_Teleporting: 2485 case MachineState_LiveSnapshotting: 2486 break; 2487 2488 case MachineState_Paused: 2489 case MachineState_TeleportingPausedVM: 2490 case MachineState_Saving: 2491 return setError(VBOX_E_INVALID_VM_STATE, tr("Already paused")); 2492 2493 default: 2494 return setInvalidMachineStateError(); 2495 } 2496 2497 /* get the VM handle. */ 2498 SafeVMPtr ptrVM(this); 2499 if (!ptrVM.isOk()) 2500 return ptrVM.rc(); 2501 2502 LogFlowThisFunc(("Sending PAUSE request...\n")); 2503 2504 /* release the lock before a VMR3* call (EMT will call us back)! */ 2505 alock.release(); 2506 2507 int vrc = VMR3Suspend(ptrVM.rawUVM()); 2508 2509 HRESULT hrc = S_OK; 2510 if (RT_FAILURE(vrc)) 2511 hrc = setError(VBOX_E_VM_ERROR, tr("Could not suspend the machine execution (%Rrc)"), vrc); 2512 2513 LogFlowThisFunc(("hrc=%Rhrc\n", hrc)); 2480 HRESULT rc = pause(Reason_Unspecified); 2481 2482 LogFlowThisFunc(("rc=%Rhrc\n", rc)); 2514 2483 LogFlowThisFuncLeave(); 2515 return hrc;2484 return rc; 2516 2485 } 2517 2486 … … 2520 2489 LogFlowThisFuncEnter(); 2521 2490 2522 AutoCaller autoCaller(this); 2523 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 2524 2525 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2526 2527 if (mMachineState != MachineState_Paused) 2528 return setError(VBOX_E_INVALID_VM_STATE, 2529 tr("Cannot resume the machine as it is not paused (machine state: %s)"), 2530 Global::stringifyMachineState(mMachineState)); 2531 2532 /* get the VM handle. */ 2533 SafeVMPtr ptrVM(this); 2534 if (!ptrVM.isOk()) 2535 return ptrVM.rc(); 2536 2537 LogFlowThisFunc(("Sending RESUME request...\n")); 2538 2539 /* release the lock before a VMR3* call (EMT will call us back)! */ 2540 alock.release(); 2541 2542 #ifdef VBOX_WITH_EXTPACK 2543 int vrc = mptrExtPackManager->callAllVmPowerOnHooks(this, VMR3GetVM(ptrVM.rawUVM())); /** @todo called a few times too many... */ 2544 #else 2545 int vrc = VINF_SUCCESS; 2546 #endif 2547 if (RT_SUCCESS(vrc)) 2548 { 2549 if (VMR3GetStateU(ptrVM.rawUVM()) == VMSTATE_CREATED) 2550 vrc = VMR3PowerOn(ptrVM.rawUVM()); /* (PowerUpPaused) */ 2551 else 2552 vrc = VMR3Resume(ptrVM.rawUVM()); 2553 } 2554 2555 HRESULT rc = RT_SUCCESS(vrc) ? S_OK : 2556 setError(VBOX_E_VM_ERROR, 2557 tr("Could not resume the machine execution (%Rrc)"), 2558 vrc); 2491 HRESULT rc = resume(Reason_Unspecified); 2559 2492 2560 2493 LogFlowThisFunc(("rc=%Rhrc\n", rc)); … … 2757 2690 { 2758 2691 LogFlowThisFuncEnter(); 2759 LogFlowThisFunc(("mMachineState=%d\n", mMachineState)); 2760 2761 CheckComArgOutPointerValid(aProgress); 2762 2763 AutoCaller autoCaller(this); 2764 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 2765 2766 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2767 2768 if ( mMachineState != MachineState_Running 2769 && mMachineState != MachineState_Paused) 2770 { 2771 return setError(VBOX_E_INVALID_VM_STATE, 2772 tr("Cannot save the execution state as the machine is not running or paused (machine state: %s)"), 2773 Global::stringifyMachineState(mMachineState)); 2774 } 2775 2776 /* memorize the current machine state */ 2777 MachineState_T lastMachineState = mMachineState; 2778 2779 if (mMachineState == MachineState_Running) 2780 { 2781 /* get the VM handle. */ 2782 SafeVMPtr ptrVM(this); 2783 if (!ptrVM.isOk()) 2784 return ptrVM.rc(); 2785 2786 /* release the lock before a VMR3* call (EMT will call us back)! */ 2787 alock.release(); 2788 int vrc = VMR3Suspend(ptrVM.rawUVM()); 2789 alock.acquire(); 2790 2791 HRESULT hrc = S_OK; 2792 if (RT_FAILURE(vrc)) 2793 hrc = setError(VBOX_E_VM_ERROR, tr("Could not suspend the machine execution (%Rrc)"), vrc); 2794 if (FAILED(hrc)) 2795 return hrc; 2796 } 2797 2798 HRESULT rc = S_OK; 2799 bool fBeganSavingState = false; 2800 bool fTaskCreationFailed = false; 2801 2802 do 2803 { 2804 ComPtr<IProgress> pProgress; 2805 Bstr stateFilePath; 2806 2807 /* 2808 * request a saved state file path from the server 2809 * (this will set the machine state to Saving on the server to block 2810 * others from accessing this machine) 2811 */ 2812 rc = mControl->BeginSavingState(pProgress.asOutParam(), 2813 stateFilePath.asOutParam()); 2814 if (FAILED(rc)) 2815 break; 2816 2817 fBeganSavingState = true; 2818 2819 /* sync the state with the server */ 2820 setMachineStateLocally(MachineState_Saving); 2821 2822 /* ensure the directory for the saved state file exists */ 2823 { 2824 Utf8Str dir = stateFilePath; 2825 dir.stripFilename(); 2826 if (!RTDirExists(dir.c_str())) 2827 { 2828 int vrc = RTDirCreateFullPath(dir.c_str(), 0700); 2829 if (RT_FAILURE(vrc)) 2830 { 2831 rc = setError(VBOX_E_FILE_ERROR, 2832 tr("Could not create a directory '%s' to save the state to (%Rrc)"), 2833 dir.c_str(), vrc); 2834 break; 2835 } 2836 } 2837 } 2838 2839 /* Create a task object early to ensure mpUVM protection is successful. */ 2840 std::auto_ptr<VMSaveTask> task(new VMSaveTask(this, pProgress, 2841 stateFilePath, 2842 lastMachineState)); 2843 rc = task->rc(); 2844 /* 2845 * If we fail here it means a PowerDown() call happened on another 2846 * thread while we were doing Pause() (which releases the Console lock). 2847 * We assign PowerDown() a higher precedence than SaveState(), 2848 * therefore just return the error to the caller. 2849 */ 2850 if (FAILED(rc)) 2851 { 2852 fTaskCreationFailed = true; 2853 break; 2854 } 2855 2856 /* create a thread to wait until the VM state is saved */ 2857 int vrc = RTThreadCreate(NULL, Console::saveStateThread, (void *)task.get(), 2858 0, RTTHREADTYPE_MAIN_WORKER, 0, "VMSave"); 2859 if (RT_FAILURE(vrc)) 2860 { 2861 rc = setError(E_FAIL, "Could not create VMSave thread (%Rrc)", vrc); 2862 break; 2863 } 2864 2865 /* task is now owned by saveStateThread(), so release it */ 2866 task.release(); 2867 2868 /* return the progress to the caller */ 2869 pProgress.queryInterfaceTo(aProgress); 2870 } while (0); 2871 2872 if (FAILED(rc) && !fTaskCreationFailed) 2873 { 2874 /* preserve existing error info */ 2875 ErrorInfoKeeper eik; 2876 2877 if (fBeganSavingState) 2878 { 2879 /* 2880 * cancel the requested save state procedure. 2881 * This will reset the machine state to the state it had right 2882 * before calling mControl->BeginSavingState(). 2883 */ 2884 mControl->EndSavingState(eik.getResultCode(), eik.getText().raw()); 2885 } 2886 2887 if (lastMachineState == MachineState_Running) 2888 { 2889 /* restore the paused state if appropriate */ 2890 setMachineStateLocally(MachineState_Paused); 2891 /* restore the running state if appropriate */ 2892 SafeVMPtr ptrVM(this); 2893 if (ptrVM.isOk()) 2894 { 2895 alock.release(); 2896 VMR3Resume(ptrVM.rawUVM()); 2897 alock.acquire(); 2898 } 2899 } 2900 else 2901 setMachineStateLocally(lastMachineState); 2902 } 2692 2693 HRESULT rc = saveState(Reason_Unspecified, aProgress); 2903 2694 2904 2695 LogFlowThisFunc(("rc=%Rhrc\n", rc)); … … 3361 3152 { 3362 3153 LogFlowThisFuncEnter(); 3363 LogFlowThisFunc(("aName='%ls' mMachineState=%d\n", aName, mMachineState));3364 3154 3365 3155 CheckComArgStrNotEmptyOrNull(aName); … … 3370 3160 3371 3161 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 3162 LogFlowThisFunc(("aName='%ls' mMachineState=%d\n", aName, mMachineState)); 3372 3163 3373 3164 if (Global::IsTransient(mMachineState)) … … 5921 5712 5922 5713 /** 5714 * Worker for Console::Pause and internal entry point for pausing a VM for 5715 * a specific reason. 5716 */ 5717 HRESULT Console::pause(Reason_T aReason) 5718 { 5719 LogFlowThisFuncEnter(); 5720 5721 AutoCaller autoCaller(this); 5722 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 5723 5724 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 5725 5726 switch (mMachineState) 5727 { 5728 case MachineState_Running: 5729 case MachineState_Teleporting: 5730 case MachineState_LiveSnapshotting: 5731 break; 5732 5733 case MachineState_Paused: 5734 case MachineState_TeleportingPausedVM: 5735 case MachineState_Saving: 5736 return setError(VBOX_E_INVALID_VM_STATE, tr("Already paused")); 5737 5738 default: 5739 return setInvalidMachineStateError(); 5740 } 5741 5742 /* get the VM handle. */ 5743 SafeVMPtr ptrVM(this); 5744 if (!ptrVM.isOk()) 5745 return ptrVM.rc(); 5746 5747 /* release the lock before a VMR3* call (EMT will call us back)! */ 5748 alock.release(); 5749 5750 LogFlowThisFunc(("Sending PAUSE request...\n")); 5751 if (aReason != Reason_Unspecified) 5752 LogRel(("Pausing VM execution, reason \"%s\"\n", Global::stringifyReason(aReason))); 5753 5754 /** @todo r=klaus make use of aReason */ 5755 int vrc = VMR3Suspend(ptrVM.rawUVM()); 5756 5757 HRESULT hrc = S_OK; 5758 if (RT_FAILURE(vrc)) 5759 hrc = setError(VBOX_E_VM_ERROR, tr("Could not suspend the machine execution (%Rrc)"), vrc); 5760 5761 LogFlowThisFunc(("hrc=%Rhrc\n", hrc)); 5762 LogFlowThisFuncLeave(); 5763 return hrc; 5764 } 5765 5766 /** 5767 * Worker for Console::Resume and internal entry point for resuming a VM for 5768 * a specific reason. 5769 */ 5770 HRESULT Console::resume(Reason_T aReason) 5771 { 5772 LogFlowThisFuncEnter(); 5773 5774 AutoCaller autoCaller(this); 5775 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 5776 5777 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 5778 5779 if (mMachineState != MachineState_Paused) 5780 return setError(VBOX_E_INVALID_VM_STATE, 5781 tr("Cannot resume the machine as it is not paused (machine state: %s)"), 5782 Global::stringifyMachineState(mMachineState)); 5783 5784 /* get the VM handle. */ 5785 SafeVMPtr ptrVM(this); 5786 if (!ptrVM.isOk()) 5787 return ptrVM.rc(); 5788 5789 /* release the lock before a VMR3* call (EMT will call us back)! */ 5790 alock.release(); 5791 5792 LogFlowThisFunc(("Sending RESUME request...\n")); 5793 if (aReason != Reason_Unspecified) 5794 LogRel(("Resuming VM execution, reason \"%s\"\n", Global::stringifyReason(aReason))); 5795 5796 /** @todo r=klaus make use of aReason */ 5797 int vrc; 5798 if (VMR3GetStateU(ptrVM.rawUVM()) == VMSTATE_CREATED) 5799 { 5800 #ifdef VBOX_WITH_EXTPACK 5801 vrc = mptrExtPackManager->callAllVmPowerOnHooks(this, VMR3GetVM(ptrVM.rawUVM())); 5802 #else 5803 vrc = VINF_SUCCESS; 5804 #endif 5805 if (RT_SUCCESS(vrc)) 5806 vrc = VMR3PowerOn(ptrVM.rawUVM()); /* (PowerUpPaused) */ 5807 } 5808 else 5809 vrc = VMR3Resume(ptrVM.rawUVM()); 5810 5811 HRESULT rc = RT_SUCCESS(vrc) ? S_OK : 5812 setError(VBOX_E_VM_ERROR, 5813 tr("Could not resume the machine execution (%Rrc)"), 5814 vrc); 5815 5816 LogFlowThisFunc(("rc=%Rhrc\n", rc)); 5817 LogFlowThisFuncLeave(); 5818 return rc; 5819 } 5820 5821 /** 5822 * Worker for Console::SaveState and internal entry point for saving state of 5823 * a VM for a specific reason. 5824 */ 5825 HRESULT Console::saveState(Reason_T aReason, IProgress **aProgress) 5826 { 5827 LogFlowThisFuncEnter(); 5828 5829 CheckComArgOutPointerValid(aProgress); 5830 5831 AutoCaller autoCaller(this); 5832 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 5833 5834 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 5835 5836 LogFlowThisFunc(("mMachineState=%d\n", mMachineState)); 5837 if ( mMachineState != MachineState_Running 5838 && mMachineState != MachineState_Paused) 5839 { 5840 return setError(VBOX_E_INVALID_VM_STATE, 5841 tr("Cannot save the execution state as the machine is not running or paused (machine state: %s)"), 5842 Global::stringifyMachineState(mMachineState)); 5843 } 5844 5845 if (aReason != Reason_Unspecified) 5846 LogRel(("Saving state of VM, reason \"%s\"\n", Global::stringifyReason(aReason))); 5847 5848 /* memorize the current machine state */ 5849 MachineState_T lastMachineState = mMachineState; 5850 5851 if (mMachineState == MachineState_Running) 5852 { 5853 /* get the VM handle. */ 5854 SafeVMPtr ptrVM(this); 5855 if (!ptrVM.isOk()) 5856 return ptrVM.rc(); 5857 5858 /* release the lock before a VMR3* call (EMT will call us back)! */ 5859 alock.release(); 5860 int vrc = VMR3Suspend(ptrVM.rawUVM()); 5861 alock.acquire(); 5862 5863 HRESULT hrc = S_OK; 5864 if (RT_FAILURE(vrc)) 5865 hrc = setError(VBOX_E_VM_ERROR, tr("Could not suspend the machine execution (%Rrc)"), vrc); 5866 if (FAILED(hrc)) 5867 return hrc; 5868 } 5869 5870 HRESULT rc = S_OK; 5871 bool fBeganSavingState = false; 5872 bool fTaskCreationFailed = false; 5873 5874 do 5875 { 5876 ComPtr<IProgress> pProgress; 5877 Bstr stateFilePath; 5878 5879 /* 5880 * request a saved state file path from the server 5881 * (this will set the machine state to Saving on the server to block 5882 * others from accessing this machine) 5883 */ 5884 rc = mControl->BeginSavingState(pProgress.asOutParam(), 5885 stateFilePath.asOutParam()); 5886 if (FAILED(rc)) 5887 break; 5888 5889 fBeganSavingState = true; 5890 5891 /* sync the state with the server */ 5892 setMachineStateLocally(MachineState_Saving); 5893 5894 /* ensure the directory for the saved state file exists */ 5895 { 5896 Utf8Str dir = stateFilePath; 5897 dir.stripFilename(); 5898 if (!RTDirExists(dir.c_str())) 5899 { 5900 int vrc = RTDirCreateFullPath(dir.c_str(), 0700); 5901 if (RT_FAILURE(vrc)) 5902 { 5903 rc = setError(VBOX_E_FILE_ERROR, 5904 tr("Could not create a directory '%s' to save the state to (%Rrc)"), 5905 dir.c_str(), vrc); 5906 break; 5907 } 5908 } 5909 } 5910 5911 /* Create a task object early to ensure mpUVM protection is successful. */ 5912 std::auto_ptr<VMSaveTask> task(new VMSaveTask(this, pProgress, 5913 stateFilePath, 5914 lastMachineState, 5915 aReason)); 5916 rc = task->rc(); 5917 /* 5918 * If we fail here it means a PowerDown() call happened on another 5919 * thread while we were doing Pause() (which releases the Console lock). 5920 * We assign PowerDown() a higher precedence than SaveState(), 5921 * therefore just return the error to the caller. 5922 */ 5923 if (FAILED(rc)) 5924 { 5925 fTaskCreationFailed = true; 5926 break; 5927 } 5928 5929 /* create a thread to wait until the VM state is saved */ 5930 int vrc = RTThreadCreate(NULL, Console::saveStateThread, (void *)task.get(), 5931 0, RTTHREADTYPE_MAIN_WORKER, 0, "VMSave"); 5932 if (RT_FAILURE(vrc)) 5933 { 5934 rc = setError(E_FAIL, "Could not create VMSave thread (%Rrc)", vrc); 5935 break; 5936 } 5937 5938 /* task is now owned by saveStateThread(), so release it */ 5939 task.release(); 5940 5941 /* return the progress to the caller */ 5942 pProgress.queryInterfaceTo(aProgress); 5943 } while (0); 5944 5945 if (FAILED(rc) && !fTaskCreationFailed) 5946 { 5947 /* preserve existing error info */ 5948 ErrorInfoKeeper eik; 5949 5950 if (fBeganSavingState) 5951 { 5952 /* 5953 * cancel the requested save state procedure. 5954 * This will reset the machine state to the state it had right 5955 * before calling mControl->BeginSavingState(). 5956 */ 5957 mControl->EndSavingState(eik.getResultCode(), eik.getText().raw()); 5958 } 5959 5960 if (lastMachineState == MachineState_Running) 5961 { 5962 /* restore the paused state if appropriate */ 5963 setMachineStateLocally(MachineState_Paused); 5964 /* restore the running state if appropriate */ 5965 SafeVMPtr ptrVM(this); 5966 if (ptrVM.isOk()) 5967 { 5968 alock.release(); 5969 VMR3Resume(ptrVM.rawUVM()); 5970 alock.acquire(); 5971 } 5972 } 5973 else 5974 setMachineStateLocally(lastMachineState); 5975 } 5976 5977 LogFlowThisFunc(("rc=%Rhrc\n", rc)); 5978 LogFlowThisFuncLeave(); 5979 return rc; 5980 } 5981 5982 /** 5923 5983 * Gets called by Session::UpdateMachineState() 5924 5984 * (IInternalSessionControl::updateMachineState()). … … 6391 6451 6392 6452 LogFlowThisFuncEnter(); 6393 LogFlowThisFunc(("mMachineState=%d\n", mMachineState));6394 6453 6395 6454 CheckComArgOutPointerValid(aProgress); … … 6400 6459 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 6401 6460 6461 LogFlowThisFunc(("mMachineState=%d\n", mMachineState)); 6402 6462 HRESULT rc = S_OK; 6403 6463 ComObjPtr<Progress> pPowerupProgress; … … 9687 9747 LogFlowFunc(("Saving the state to '%s'...\n", task->mSavedStateFile.c_str())); 9688 9748 9749 /** @todo r=klaus make use of task->mReason */ 9689 9750 bool fSuspenededBySave; 9690 9751 int vrc = VMR3Save(task->mpUVM, -
trunk/src/VBox/Main/src-client/SessionImpl.cpp
r46465 r46775 926 926 927 927 return S_OK; 928 } 929 930 STDMETHODIMP Session::PauseWithReason(Reason_T aReason) 931 { 932 AutoCaller autoCaller(this); 933 AssertComRCReturn(autoCaller.rc(), autoCaller.rc()); 934 935 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 936 AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE); 937 AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE); 938 AssertReturn(mConsole, VBOX_E_INVALID_OBJECT_STATE); 939 940 return mConsole->pause(aReason); 941 } 942 943 STDMETHODIMP Session::ResumeWithReason(Reason_T aReason) 944 { 945 AutoCaller autoCaller(this); 946 AssertComRCReturn(autoCaller.rc(), autoCaller.rc()); 947 948 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 949 AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE); 950 AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE); 951 AssertReturn(mConsole, VBOX_E_INVALID_OBJECT_STATE); 952 953 return mConsole->resume(aReason); 954 } 955 956 STDMETHODIMP Session::SaveStateWithReason(Reason_T aReason, IProgress **aProgress) 957 { 958 AutoCaller autoCaller(this); 959 AssertComRCReturn(autoCaller.rc(), autoCaller.rc()); 960 961 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 962 AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE); 963 AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE); 964 AssertReturn(mConsole, VBOX_E_INVALID_OBJECT_STATE); 965 966 return mConsole->saveState(aReason, aProgress); 928 967 } 929 968 -
trunk/src/VBox/Main/src-server/HostPower.cpp
r44528 r46775 5 5 6 6 /* 7 * Copyright (C) 2006-201 1Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 27 27 28 28 #include "VirtualBoxImpl.h" 29 #include "MachineImpl.h" 29 30 30 31 #include <iprt/mem.h> 31 32 32 HostPowerService::HostPowerService (VirtualBox *aVirtualBox)33 HostPowerService::HostPowerService(VirtualBox *aVirtualBox) 33 34 { 34 35 Assert(aVirtualBox != NULL); … … 40 41 } 41 42 42 void HostPowerService::notify( HostPowerEvent aEvent)43 void HostPowerService::notify(Reason_T aReason) 43 44 { 44 45 SessionMachinesList machines; … … 47 48 HRESULT rc = S_OK; 48 49 49 switch (a Event)50 switch (aReason) 50 51 { 51 case HostPowerEvent_Suspend:52 case Reason_HostSuspend: 52 53 { 53 LogFunc (("SUSPEND\n"));54 LogFunc(("SUSPEND\n")); 54 55 55 56 #ifdef VBOX_WITH_RESOURCE_USAGE_API … … 69 70 ComPtr<IInternalSessionControl> pControl = *it; 70 71 71 /* get the remote console */ 72 ComPtr<IConsole> console; 73 rc = pControl->GetRemoteConsole(console.asOutParam()); 74 /* the VM could have been powered down and closed or whatever */ 75 if (FAILED(rc)) 76 continue; 77 78 /* note that Pause() will simply return a failure if the VM is 79 * in an inappropriate state */ 80 rc = console->Pause(); 72 /* PauseWithReason() will simply return a failure if 73 * the VM is in an inappropriate state */ 74 rc = pControl->PauseWithReason(Reason_HostSuspend); 81 75 if (FAILED(rc)) 82 76 continue; 83 77 84 78 /* save the control to un-pause the VM later */ 85 m Consoles.push_back(console);79 mSessionControls.push_back(pControl); 86 80 } 87 81 88 LogFunc (("Suspended %d VMs\n", mConsoles.size()));82 LogFunc(("Suspended %d VMs\n", mSessionControls.size())); 89 83 90 84 break; 91 85 } 92 86 93 case HostPowerEvent_Resume:87 case Reason_HostResume: 94 88 { 95 LogFunc (("RESUME\n"));89 LogFunc(("RESUME\n")); 96 90 97 91 size_t resumed = 0; 98 92 99 93 /* go through VMs we paused on Suspend */ 100 for (size_t i = 0; i < m Consoles.size(); ++i)94 for (size_t i = 0; i < mSessionControls.size(); ++i) 101 95 { 102 96 /* note that Resume() will simply return a failure if the VM is … … 104 98 * been somehow closed by this time already so that the 105 99 * console reference we have is dead) */ 106 rc = m Consoles[i]->Resume();100 rc = mSessionControls[i]->ResumeWithReason(Reason_HostResume); 107 101 if (FAILED(rc)) 108 102 continue; 109 103 110 ++ resumed;104 ++resumed; 111 105 } 112 106 113 LogFunc (("Resumed %d VMs\n", resumed));107 LogFunc(("Resumed %d VMs\n", resumed)); 114 108 115 109 #ifdef VBOX_WITH_RESOURCE_USAGE_API … … 121 115 #endif 122 116 123 m Consoles.clear();117 mSessionControls.clear(); 124 118 125 119 break; 126 120 } 127 121 128 case HostPowerEvent_BatteryLow:122 case Reason_HostBatteryLow: 129 123 { 130 LogFunc (("BATTERY LOW\n"));124 LogFunc(("BATTERY LOW\n")); 131 125 132 126 mVirtualBox->getOpenedMachines(machines, &controls); … … 140 134 { 141 135 ComPtr<IInternalSessionControl> pControl = *it; 142 /* get the remote console */143 ComPtr<IConsole> console;144 rc = pControl->GetRemoteConsole (console.asOutParam());145 /* the VM could have been powered down and closed or whatever */146 if (FAILED(rc))147 continue;148 136 149 137 ComPtr<IProgress> progress; 150 138 151 /* note that SaveState () will simply return a failure if the VM152 * i s in an inappropriate state */153 rc = console->SaveState (progress.asOutParam());139 /* note that SaveStateWithReason() will simply return a failure 140 * if the VM is in an inappropriate state */ 141 rc = pControl->SaveStateWithReason(Reason_HostBatteryLow, progress.asOutParam()); 154 142 if (FAILED(rc)) 155 143 continue; … … 164 152 } 165 153 166 AssertMsg (SUCCEEDED(rc), ("SaveState WaitForCompletion " 167 "failed with %Rhrc (%#08X)\n", rc, rc)); 154 AssertMsg(SUCCEEDED(rc), ("SaveState WaitForCompletion failed with %Rhrc (%#08X)\n", rc, rc)); 168 155 169 156 if (SUCCEEDED(rc)) 170 ++ saved;157 ++saved; 171 158 } 172 159 173 LogFunc (("Saved %d VMs\n", saved));160 LogFunc(("Saved %d VMs\n", saved)); 174 161 175 162 break; 176 163 } 164 165 default: 166 /* nothing */; 177 167 } 178 168 } -
trunk/src/VBox/Main/src-server/darwin/HostPowerDarwin.cpp
r44529 r46775 5 5 6 6 /* 7 * Copyright (C) 2008-201 0Oracle Corporation7 * Copyright (C) 2008-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 26 26 #define POWER_SOURCE_BATTERY 2 27 27 28 HostPowerServiceDarwin::HostPowerServiceDarwin (VirtualBox *aVirtualBox)29 : HostPowerService (aVirtualBox)30 , mThread (NULL)31 , mRootPort (MACH_PORT_NULL)32 , mNotifyPort (nil)33 , mRunLoop (nil)34 , mCritical (false)28 HostPowerServiceDarwin::HostPowerServiceDarwin(VirtualBox *aVirtualBox) 29 : HostPowerService(aVirtualBox) 30 , mThread(NULL) 31 , mRootPort(MACH_PORT_NULL) 32 , mNotifyPort(nil) 33 , mRunLoop(nil) 34 , mCritical(false) 35 35 { 36 36 /* Create the new worker thread. */ 37 int rc = RTThreadCreate (&mThread, HostPowerServiceDarwin::powerChangeNotificationThread, this, 65536,38 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "MainPower");37 int rc = RTThreadCreate(&mThread, HostPowerServiceDarwin::powerChangeNotificationThread, this, 65536, 38 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "MainPower"); 39 39 40 40 if (RT_FAILURE(rc)) 41 LogFlow (("RTThreadCreate failed with %Rrc\n", rc));41 LogFlow(("RTThreadCreate failed with %Rrc\n", rc)); 42 42 } 43 43 … … 45 45 { 46 46 /* Jump out of the run loop. */ 47 CFRunLoopStop (mRunLoop);47 CFRunLoopStop(mRunLoop); 48 48 /* Remove the sleep notification port from the application runloop. */ 49 CFRunLoopRemoveSource (CFRunLoopGetCurrent(),50 IONotificationPortGetRunLoopSource(mNotifyPort),51 kCFRunLoopCommonModes);49 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), 50 IONotificationPortGetRunLoopSource(mNotifyPort), 51 kCFRunLoopCommonModes); 52 52 /* Deregister for system sleep notifications. */ 53 IODeregisterForSystemPower (&mNotifierObject);53 IODeregisterForSystemPower(&mNotifierObject); 54 54 /* IORegisterForSystemPower implicitly opens the Root Power Domain 55 55 * IOService so we close it here. */ 56 IOServiceClose (mRootPort);56 IOServiceClose(mRootPort); 57 57 /* Destroy the notification port allocated by IORegisterForSystemPower */ 58 IONotificationPortDestroy (mNotifyPort);59 } 60 61 62 DECLCALLBACK(int) HostPowerServiceDarwin::powerChangeNotificationThread (RTTHREAD /* ThreadSelf */, void *pInstance)63 { 64 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *> (pInstance);58 IONotificationPortDestroy(mNotifyPort); 59 } 60 61 62 DECLCALLBACK(int) HostPowerServiceDarwin::powerChangeNotificationThread(RTTHREAD /* ThreadSelf */, void *pInstance) 63 { 64 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *>(pInstance); 65 65 66 66 /* We have to initial set the critical state of the battery, cause we want … … 70 70 71 71 /* Register to receive system sleep notifications */ 72 pPowerObj->mRootPort = IORegisterForSystemPower (pPowerObj, &pPowerObj->mNotifyPort,73 HostPowerServiceDarwin::powerChangeNotificationHandler,74 &pPowerObj->mNotifierObject);72 pPowerObj->mRootPort = IORegisterForSystemPower(pPowerObj, &pPowerObj->mNotifyPort, 73 HostPowerServiceDarwin::powerChangeNotificationHandler, 74 &pPowerObj->mNotifierObject); 75 75 if (pPowerObj->mRootPort == MACH_PORT_NULL) 76 76 { 77 LogFlow (("IORegisterForSystemPower failed\n"));77 LogFlow(("IORegisterForSystemPower failed\n")); 78 78 return VERR_NOT_SUPPORTED; 79 79 } 80 80 pPowerObj->mRunLoop = CFRunLoopGetCurrent(); 81 81 /* Add the notification port to the application runloop */ 82 CFRunLoopAddSource (pPowerObj->mRunLoop,83 IONotificationPortGetRunLoopSource(pPowerObj->mNotifyPort),84 kCFRunLoopCommonModes);82 CFRunLoopAddSource(pPowerObj->mRunLoop, 83 IONotificationPortGetRunLoopSource(pPowerObj->mNotifyPort), 84 kCFRunLoopCommonModes); 85 85 86 86 /* Register for all battery change events. The handler will check for low … … 97 97 } 98 98 99 void HostPowerServiceDarwin::powerChangeNotificationHandler (void *pvData, io_service_t /* service */, natural_t messageType, void *pMessageArgument)100 { 101 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *> (pvData);102 Log (( "powerChangeNotificationHandler: messageType %08lx, arg %08lx\n", (long unsigned int)messageType, (long unsigned int)pMessageArgument));99 void HostPowerServiceDarwin::powerChangeNotificationHandler(void *pvData, io_service_t /* service */, natural_t messageType, void *pMessageArgument) 100 { 101 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *>(pvData); 102 Log(( "powerChangeNotificationHandler: messageType %08lx, arg %08lx\n", (long unsigned int)messageType, (long unsigned int)pMessageArgument)); 103 103 104 104 switch (messageType) … … 114 114 * IOAllowPowerChange or IOCancelPowerChange, the system will 115 115 * wait 30 seconds then go to sleep. */ 116 IOAllowPowerChange (pPowerObj->mRootPort, reinterpret_cast<long>(pMessageArgument));116 IOAllowPowerChange(pPowerObj->mRootPort, reinterpret_cast<long>(pMessageArgument)); 117 117 break; 118 118 } … … 120 120 { 121 121 /* The system will go for sleep. */ 122 pPowerObj->notify (HostPowerEvent_Suspend);122 pPowerObj->notify(Reason_HostSuspend); 123 123 /* If you do not call IOAllowPowerChange or IOCancelPowerChange to 124 124 * acknowledge this message, sleep will be delayed by 30 seconds. 125 125 * NOTE: If you call IOCancelPowerChange to deny sleep it returns 126 126 * kIOReturnSuccess, however the system WILL still go to sleep. */ 127 IOAllowPowerChange (pPowerObj->mRootPort, reinterpret_cast<long>(pMessageArgument));127 IOAllowPowerChange(pPowerObj->mRootPort, reinterpret_cast<long>(pMessageArgument)); 128 128 break; 129 129 } … … 136 136 { 137 137 /* System has finished the wake up process. */ 138 pPowerObj->notify (HostPowerEvent_Resume);138 pPowerObj->notify(Reason_HostResume); 139 139 break; 140 140 } … … 144 144 } 145 145 146 void HostPowerServiceDarwin::lowPowerHandler (void *pvData)147 { 148 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *> (pvData);149 150 /* Following role for sending the BatteryLow event (5% is critical):146 void HostPowerServiceDarwin::lowPowerHandler(void *pvData) 147 { 148 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *>(pvData); 149 150 /* Following role for sending the BatteryLow event(5% is critical): 151 151 * - Not at VM start even if the battery is in an critical state already. 152 152 * - When the power cord is removed so the power supply change from AC to … … 157 157 * normal triggers nothing. */ 158 158 bool fCriticalStateChanged = false; 159 pPowerObj->checkBatteryCriticalLevel (&fCriticalStateChanged);159 pPowerObj->checkBatteryCriticalLevel(&fCriticalStateChanged); 160 160 if (fCriticalStateChanged) 161 pPowerObj->notify (HostPowerEvent_BatteryLow);162 } 163 164 void HostPowerServiceDarwin::checkBatteryCriticalLevel (bool *pfCriticalChanged)161 pPowerObj->notify(Reason_HostBatteryLow); 162 } 163 164 void HostPowerServiceDarwin::checkBatteryCriticalLevel(bool *pfCriticalChanged) 165 165 { 166 166 CFTypeRef pBlob = IOPSCopyPowerSourcesInfo(); 167 CFArrayRef pSources = IOPSCopyPowerSourcesList (pBlob);167 CFArrayRef pSources = IOPSCopyPowerSourcesList(pBlob); 168 168 169 169 CFDictionaryRef pSource = NULL; … … 173 173 bool critical = false; 174 174 175 if (CFArrayGetCount (pSources) > 0)175 if (CFArrayGetCount(pSources) > 0) 176 176 { 177 for (int i = 0; i < CFArrayGetCount (pSources); ++i)177 for (int i = 0; i < CFArrayGetCount(pSources); ++i) 178 178 { 179 pSource = IOPSGetPowerSourceDescription (pBlob, CFArrayGetValueAtIndex(pSources, i));179 pSource = IOPSGetPowerSourceDescription(pBlob, CFArrayGetValueAtIndex(pSources, i)); 180 180 /* If the source is empty skip over to the next one. */ 181 181 if (!pSource) … … 183 183 /* Skip all power sources which are currently not present like a 184 184 * second battery. */ 185 if (CFDictionaryGetValue (pSource, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse)185 if (CFDictionaryGetValue(pSource, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse) 186 186 continue; 187 187 /* Only internal power types are of interest. */ 188 result = CFDictionaryGetValueIfPresent (pSource, CFSTR(kIOPSTransportTypeKey), &psValue);188 result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSTransportTypeKey), &psValue); 189 189 if (result && 190 CFStringCompare ((CFStringRef)psValue, CFSTR(kIOPSInternalType), 0) == kCFCompareEqualTo)190 CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSInternalType), 0) == kCFCompareEqualTo) 191 191 { 192 192 /* First check which power source we are connect on. */ 193 result = CFDictionaryGetValueIfPresent (pSource, CFSTR(kIOPSPowerSourceStateKey), &psValue);193 result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSPowerSourceStateKey), &psValue); 194 194 if (result && 195 CFStringCompare ((CFStringRef)psValue, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo)195 CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo) 196 196 powerSource = POWER_SOURCE_OUTLET; 197 197 else if (result && 198 CFStringCompare ((CFStringRef)psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo)198 CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo) 199 199 powerSource = POWER_SOURCE_BATTERY; 200 200 … … 204 204 205 205 /* Fetch the current capacity value of the power source */ 206 result = CFDictionaryGetValueIfPresent (pSource, CFSTR(kIOPSCurrentCapacityKey), &psValue);206 result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSCurrentCapacityKey), &psValue); 207 207 if (result) 208 CFNumberGetValue ((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity);208 CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity); 209 209 /* Fetch the maximum capacity value of the power source */ 210 result = CFDictionaryGetValueIfPresent (pSource, CFSTR(kIOPSMaxCapacityKey), &psValue);210 result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSMaxCapacityKey), &psValue); 211 211 if (result) 212 CFNumberGetValue ((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity);212 CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity); 213 213 214 214 /* Calculate the remaining capacity in percent */ … … 217 217 /* Check for critical. 5 percent is default. */ 218 218 int criticalValue = 5; 219 result = CFDictionaryGetValueIfPresent (pSource, CFSTR(kIOPSDeadWarnLevelKey), &psValue);219 result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSDeadWarnLevelKey), &psValue); 220 220 if (result) 221 CFNumberGetValue ((CFNumberRef)psValue, kCFNumberSInt32Type, &criticalValue);221 CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &criticalValue); 222 222 critical = (remCapacity < criticalValue); 223 223 /* We have to take action only if we are on battery, the … … 229 229 pfCriticalChanged) 230 230 *pfCriticalChanged = true; 231 Log (("checkBatteryCriticalLevel: Remains: %d.%d%% Critical: %d Critical State Changed: %d\n", (int)remCapacity, (int)(remCapacity * 10) % 10, critical, pfCriticalChanged?*pfCriticalChanged:-1));231 Log(("checkBatteryCriticalLevel: Remains: %d.%d%% Critical: %d Critical State Changed: %d\n", (int)remCapacity, (int)(remCapacity * 10) % 10, critical, pfCriticalChanged?*pfCriticalChanged:-1)); 232 232 } 233 233 } … … 236 236 mCritical = critical; 237 237 238 CFRelease (pBlob);239 CFRelease (pSources);240 } 241 238 CFRelease(pBlob); 239 CFRelease(pSources); 240 } 241 -
trunk/src/VBox/Main/src-server/win/HostPowerWin.cpp
r46722 r46775 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 36 36 mHwnd = 0; 37 37 38 int rc = RTThreadCreate (&mThread, HostPowerServiceWin::NotificationThread, this, 65536,39 RTTHREADTYPE_GUI, RTTHREADFLAGS_WAITABLE, "MainPower");38 int rc = RTThreadCreate(&mThread, HostPowerServiceWin::NotificationThread, this, 65536, 39 RTTHREADTYPE_GUI, RTTHREADFLAGS_WAITABLE, "MainPower"); 40 40 41 41 if (RT_FAILURE(rc)) … … 63 63 64 64 65 DECLCALLBACK(int) HostPowerServiceWin::NotificationThread (RTTHREAD ThreadSelf, void *pInstance)65 DECLCALLBACK(int) HostPowerServiceWin::NotificationThread(RTTHREAD ThreadSelf, void *pInstance) 66 66 { 67 67 HostPowerServiceWin *pPowerObj = (HostPowerServiceWin *)pInstance; … … 71 71 int rc = VINF_SUCCESS; 72 72 73 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle (NULL);73 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); 74 74 75 75 /* Register the Window Class. */ … … 97 97 { 98 98 /* Create the window. */ 99 hwnd = pPowerObj->mHwnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,100 gachWindowClassName, gachWindowClassName,101 WS_POPUPWINDOW,102 -200, -200, 100, 100, NULL, NULL, hInstance, NULL);99 hwnd = pPowerObj->mHwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST, 100 gachWindowClassName, gachWindowClassName, 101 WS_POPUPWINDOW, 102 -200, -200, 100, 100, NULL, NULL, hInstance, NULL); 103 103 104 104 if (hwnd == NULL) … … 124 124 Log(("HostPowerServiceWin::NotificationThread: exit thread\n")); 125 125 if (hwnd) 126 DestroyWindow (hwnd);126 DestroyWindow(hwnd); 127 127 128 128 if (atomWindowClass != 0) 129 129 { 130 UnregisterClass (gachWindowClassName, hInstance);130 UnregisterClass(gachWindowClassName, hInstance); 131 131 atomWindowClass = 0; 132 132 } … … 149 149 { 150 150 case PBT_APMSUSPEND: 151 pPowerObj->notify( HostPowerEvent_Suspend);151 pPowerObj->notify(Reason_HostSuspend); 152 152 break; 153 153 154 154 case PBT_APMRESUMEAUTOMATIC: 155 pPowerObj->notify( HostPowerEvent_Resume);155 pPowerObj->notify(Reason_HostResume); 156 156 break; 157 157 … … 180 180 && BatteryState.EstimatedTime < 60*5) 181 181 { 182 pPowerObj->notify( HostPowerEvent_BatteryLow);182 pPowerObj->notify(Reason_HostBatteryLow); 183 183 } 184 184 } … … 187 187 if (SystemPowerStatus.BatteryFlag == 4 /* critical battery status; less than 5% */) 188 188 { 189 pPowerObj->notify( HostPowerEvent_BatteryLow);189 pPowerObj->notify(Reason_HostBatteryLow); 190 190 } 191 191 } … … 194 194 } 195 195 default: 196 return DefWindowProc (hwnd, msg, wParam, lParam);196 return DefWindowProc(hwnd, msg, wParam, lParam); 197 197 } 198 198 } … … 201 201 202 202 default: 203 return DefWindowProc (hwnd, msg, wParam, lParam);204 } 205 } 203 return DefWindowProc(hwnd, msg, wParam, lParam); 204 } 205 }
Note:
See TracChangeset
for help on using the changeset viewer.

