66 #include < Windows.h>
77 #include < thread>
88
9- static std::thread threadMessageLoop;
9+ static DWORD gMainThreadId ;
10+ static std::thread gThreadMessageLoop ;
1011#endif
1112
1213#include < csignal>
@@ -71,7 +72,6 @@ static ::LRESULT CALLBACK WndProc(const ::HWND hWnd, const ::UINT message, const
7172 switch (message)
7273 {
7374 case SIGTERM:
74- case WM_CLOSE:
7575 {
7676 handlerSigTerm (message);
7777 ::PostMessage (hWnd, WM_QUIT, 0 , 0 ); // Fuck ::PostQuitMessage(0);
@@ -99,6 +99,21 @@ static ::LRESULT CALLBACK WndProc(const ::HWND hWnd, const ::UINT message, const
9999 break ;
100100 }
101101
102+ // Cases WM_QUERYENDSESSION and WM_ENDSESSION run before shutting down the system (or ending user session)
103+ case WM_QUERYENDSESSION:
104+ {
105+ handlerSigTerm (message);
106+ break ;
107+ }
108+
109+ case WM_ENDSESSION:
110+ {
111+ ::HANDLE hThread = ::OpenThread (SYNCHRONIZE, false , gMainThreadId );
112+ ::WaitForSingleObject (hThread, INFINITE);
113+ ::CloseHandle (hThread);
114+ break ;
115+ }
116+
102117 default :
103118 {
104119 return ::DefWindowProc (hWnd, message, wParam, lParam);
@@ -136,9 +151,18 @@ static ::BOOL consoleSignalHandler(const ::DWORD ctrlType)
136151 switch (ctrlType)
137152 {
138153 case CTRL_CLOSE_EVENT:
154+ // Cases CTRL_LOGOFF_EVENT and CTRL_SHUTDOWN_EVENT don't happen because... it's Windows %)
155+ // @see my function WndProc -> cases WM_QUERYENDSESSION and WM_ENDSESSION. Only they happen in this program, because the library user32.dll is connected.
156+ // @prooflink: https://msdn.microsoft.com/library/windows/desktop/ms686016(v=vs.85).aspx
157+ case CTRL_LOGOFF_EVENT:
158+ case CTRL_SHUTDOWN_EVENT:
159+ {
139160 handlerSigTerm (ctrlType);
140- std::this_thread::sleep_for (std::chrono::seconds (60 ) );
161+ ::HANDLE hThread = ::OpenThread (SYNCHRONIZE, false , gMainThreadId );
162+ ::WaitForSingleObject (hThread, INFINITE);
163+ ::CloseHandle (hThread);
141164 return true ;
165+ }
142166
143167 case CTRL_C_EVENT:
144168 handlerSigInt (ctrlType);
@@ -180,7 +204,8 @@ bool bindSignalHandlers(HttpServer::Server *server)
180204
181205 HttpServer::Event eventWindowCreation;
182206
183- threadMessageLoop = std::thread (mainMessageLoop, hInstance, &eventWindowCreation);
207+ gMainThreadId = ::GetCurrentThreadId ();
208+ gThreadMessageLoop = std::thread (mainMessageLoop, hInstance, &eventWindowCreation);
184209
185210 eventWindowCreation.wait ();
186211
@@ -213,6 +238,6 @@ void stopSignalHandlers()
213238{
214239#ifdef WIN32
215240 System::sendSignal (::GetCurrentProcessId (), SIGINT);
216- threadMessageLoop .join ();
241+ gThreadMessageLoop .join ();
217242#endif
218243}
0 commit comments