@@ -351,10 +351,9 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
351
351
LLWindowWin32Thread ();
352
352
353
353
void run () override ;
354
- void close () override ;
355
354
356
355
// closes queue, wakes thread, waits until thread closes
357
- void wakeAndDestroy ();
356
+ bool wakeAndDestroy ();
358
357
359
358
void glReady ()
360
359
{
@@ -425,6 +424,7 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
425
424
// *HACK: Attempt to prevent startup crashes by deferring memory accounting
426
425
// until after some graphics setup. See SL-20177. -Cosmic,2023-09-18
427
426
bool mGLReady = false ;
427
+ bool mDeleteOnExit = false ;
428
428
// best guess at available video memory in MB
429
429
std::atomic<U32> mAvailableVRAM ;
430
430
@@ -997,7 +997,11 @@ void LLWindowWin32::close()
997
997
mhDC = NULL ;
998
998
mWindowHandle = NULL ;
999
999
1000
- mWindowThread ->wakeAndDestroy ();
1000
+ if (mWindowThread ->wakeAndDestroy ())
1001
+ {
1002
+ // thread will delete itselfs once done
1003
+ mWindowThread = NULL ;
1004
+ }
1001
1005
}
1002
1006
1003
1007
BOOL LLWindowWin32::isValid ()
@@ -3104,10 +3108,17 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
3104
3108
break ;
3105
3109
}
3106
3110
}
3107
- else
3111
+ else // (NULL == window_imp)
3108
3112
{
3109
- // (NULL == window_imp)
3110
- LL_DEBUGS (" Window" ) << " No window implementation to handle message with, message code: " << U32 (u_msg) << LL_ENDL;
3113
+ if (u_msg == WM_DESTROY)
3114
+ {
3115
+ PostQuitMessage (0 ); // Posts WM_QUIT with an exit code of 0
3116
+ return 0 ;
3117
+ }
3118
+ else
3119
+ {
3120
+ LL_DEBUGS (" Window" ) << " No window implementation to handle message with, message code: " << U32 (u_msg) << LL_ENDL;
3121
+ }
3111
3122
}
3112
3123
3113
3124
// pass unhandled messages down to Windows
@@ -4563,25 +4574,11 @@ U32 LLWindowWin32::getAvailableVRAMMegabytes()
4563
4574
#endif // LL_WINDOWS
4564
4575
4565
4576
inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread ()
4566
- : LL::ThreadPool(" Window Thread" , 1 , MAX_QUEUE_SIZE, true /* should be false, temporary workaround for SL-18721 */ )
4577
+ : LL::ThreadPool(" Window Thread" , 1 , MAX_QUEUE_SIZE, false )
4567
4578
{
4568
4579
LL::ThreadPool::start ();
4569
4580
}
4570
4581
4571
- void LLWindowWin32::LLWindowWin32Thread::close ()
4572
- {
4573
- if (!mQueue ->isClosed ())
4574
- {
4575
- LL_WARNS () << " Closing window thread without using destroy_window_handler" << LL_ENDL;
4576
- LL::ThreadPool::close ();
4577
-
4578
- // Workaround for SL-18721 in case window closes too early and abruptly
4579
- LLSplashScreen::show ();
4580
- LLSplashScreen::update (" ..." ); // will be updated later
4581
- }
4582
- }
4583
-
4584
-
4585
4582
/* *
4586
4583
* LogChange is to log changes in status while trying to avoid spamming the
4587
4584
* log with repeated messages, especially in a tight loop. It refuses to log
@@ -4926,14 +4923,19 @@ void LLWindowWin32::LLWindowWin32Thread::run()
4926
4923
}
4927
4924
4928
4925
cleanupDX ();
4926
+
4927
+ if (mDeleteOnExit )
4928
+ {
4929
+ delete this ;
4930
+ }
4929
4931
}
4930
4932
4931
- void LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy ()
4933
+ bool LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy ()
4932
4934
{
4933
4935
if (mQueue ->isClosed ())
4934
4936
{
4935
- LL_WARNS () << " Tried to close Queue. Win32 thread Queue already closed." << LL_ENDL;
4936
- return ;
4937
+ LL_WARNS () << " Tried to close Queue. Win32 thread Queue already closed." <<LL_ENDL;
4938
+ return false ;
4937
4939
}
4938
4940
4939
4941
// Make sure we don't leave a blank toolbar button.
@@ -4972,6 +4974,15 @@ void LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy()
4972
4974
mGLReady = false ;
4973
4975
});
4974
4976
4977
+ mDeleteOnExit = true ;
4978
+ SetWindowLongPtr (old_handle, GWLP_USERDATA, NULL );
4979
+
4980
+ // Let thread finish on its own and don't block main thread.
4981
+ for (auto & pair : mThreads )
4982
+ {
4983
+ pair.second .detach ();
4984
+ }
4985
+
4975
4986
LL_DEBUGS (" Window" ) << " Closing window's pool queue" << LL_ENDL;
4976
4987
mQueue ->close ();
4977
4988
@@ -4986,49 +4997,8 @@ void LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy()
4986
4997
PostMessage (old_handle, WM_DUMMY_, wparam, 0x1337 );
4987
4998
}
4988
4999
4989
- // There are cases where window will refuse to close,
4990
- // can't wait forever on join, check state instead
4991
- LLTimer timeout;
4992
- timeout.setTimerExpirySec (2.0 );
4993
- while (!getQueue ().done () && !timeout.hasExpired () && mWindowHandleThrd )
4994
- {
4995
- ms_sleep (100 );
4996
- }
4997
-
4998
- if (getQueue ().done () || mWindowHandleThrd == NULL )
4999
- {
5000
- // Window is closed, started closing or is cleaning up
5001
- // now wait for our single thread to die.
5002
- if (mWindowHandleThrd )
5003
- {
5004
- LL_INFOS (" Window" ) << " Window is closing, waiting on pool's thread to join, time since post: " << timeout.getElapsedSeconds () << " s" << LL_ENDL;
5005
- }
5006
- else
5007
- {
5008
- LL_DEBUGS (" Window" ) << " Waiting on pool's thread, time since post: " << timeout.getElapsedSeconds () << " s" << LL_ENDL;
5009
- }
5010
- for (auto & pair : mThreads )
5011
- {
5012
- pair.second .join ();
5013
- }
5014
- }
5015
- else
5016
- {
5017
- // Something suspended window thread, can't afford to wait forever
5018
- // so kill thread instead
5019
- // Ex: This can happen if user starts dragging window arround (if it
5020
- // was visible) or a modal notification pops up
5021
- LL_WARNS (" Window" ) << " Window is frozen, couldn't perform clean exit" << LL_ENDL;
5022
-
5023
- for (auto & pair : mThreads )
5024
- {
5025
- // very unsafe
5026
- TerminateThread (pair.second .native_handle (), 0 );
5027
- pair.second .detach ();
5028
- cleanupDX ();
5029
- }
5030
- }
5031
5000
LL_DEBUGS (" Window" ) << " thread pool shutdown complete" << LL_ENDL;
5001
+ return true ;
5032
5002
}
5033
5003
5034
5004
void LLWindowWin32::post (const std::function<void ()>& func)
0 commit comments