@@ -2814,30 +2814,6 @@ void LxssUserSessionImpl::_CreateVm()
28142814
28152815 try
28162816 {
2817- auto callback = [this ](auto Pid) {
2818- // If the vm is currently being destroyed, the instance lock might be held
2819- // while WslCoreVm's destructor is waiting on this thread.
2820- // Cancel the call if the vm destruction is signaled.
2821- // Note: This is safe because m_instanceLock is always initialized
2822- // and because WslCoreVm's destructor waits for this thread, the session can't be gone
2823- // until this callback completes.
2824-
2825- auto lock = m_instanceLock.try_lock ();
2826- while (!lock)
2827- {
2828- if (m_vmTerminating.wait (100 ))
2829- {
2830- return ;
2831- }
2832- lock = m_instanceLock.try_lock ();
2833- }
2834-
2835- auto unlock = wil::scope_exit ([&]() { m_instanceLock.unlock (); });
2836- TerminateByClientIdLockHeld (Pid);
2837- };
2838-
2839- m_utilityVm->RegisterCallbacks (std::bind (callback, _1), std::bind (s_VmTerminated, this , _1));
2840-
28412817 // Mount disks after the system distro vhd is mounted in case filesystem detection is needed.
28422818 _LoadDiskMounts ();
28432819
@@ -2869,6 +2845,34 @@ void LxssUserSessionImpl::_CreateVm()
28692845 _VmTerminate ();
28702846 throw ;
28712847 }
2848+
2849+ auto callback = [this ](auto Pid) {
2850+ // If the vm is currently being destroyed, the instance lock might be held
2851+ // while WslCoreVm's destructor is waiting on this thread.
2852+ // Cancel the call if the vm destruction is signaled.
2853+ // Note: This is safe because m_instanceLock is always initialized
2854+ // and because WslCoreVm's destructor waits for this thread, the session can't be gone
2855+ // until this callback completes.
2856+
2857+ auto lock = m_instanceLock.try_lock ();
2858+ while (!lock)
2859+ {
2860+ if (m_vmTerminating.wait (100 ))
2861+ {
2862+ return ;
2863+ }
2864+ lock = m_instanceLock.try_lock ();
2865+ }
2866+
2867+ auto unlock = wil::scope_exit ([&]() { m_instanceLock.unlock (); });
2868+ TerminateByClientIdLockHeld (Pid);
2869+ };
2870+
2871+ // N.B. The callbacks must be registered outside of the above try/catch.
2872+ // Otherwise if an exception is thrown, calling _VmTerminate() will trigger the 's_VmTerminated' termination callback
2873+ // Which can deadlock since this thread holds the instance lock and HCS can block until the VM termination callback returns before deleting the VM.
2874+
2875+ m_utilityVm->RegisterCallbacks (std::bind (callback, _1), std::bind (s_VmTerminated, this , _1));
28722876 }
28732877
28742878 _VmCheckIdle ();
0 commit comments