Bug #2901

Application sessions are not always terminated cleanly

Added by Eivind Midtgård over 8 years ago. Updated over 8 years ago.

Target version:
Start date:
Due date:
% Done:


Estimated time:


On Windows: When I generate a CTRL_CLOSE_EVENT (by pressing the 'close button'), the program stops and my application objects are not destructed. WebSession::~WebSession is not called. It works when I generate a CTRL_C_EVENT (by pressing ctrl-C).

if (server.start())

I had this problem in another program a long time ago. There I made the handler routine wait until the main thread reported that it had terminated:

HANDLE g_processStopEvent      = ::CreateEvent(0, 1, 0, 0);
HANDLE g_privateStopIsComplete = ::CreateEvent(0, 0, 0, 0);

BOOL WINAPI console_ctrl_handler(DWORD dwCtrlType)
    DWORD timeout = 4500;

    case CTRL_C_EVENT:      // Fall through
        timeout = 4500;     // A little shorter than the hardcoded value in Windows

    case CTRL_LOGOFF_EVENT: // Fall through
        timeout = 19000;    // A little shorter than the hardcoded value in Windows

    ::SetEvent(g_processStopEvent);  // Signal process it must stop

    // Wait for stop to complete, but no longer than the hardcoded timeout in Windows (5 seconds, or 20 seconds)
    ::WaitForSingleObject(g_privateStopIsComplete, timeout);
    Sleep(100);        // Just to make sure the main thread has a chance to finish completely
    return TRUE;




Updated by Koen Deforche over 8 years ago

  • Status changed from New to InProgress
  • Assignee set to Wim Dumon
  • Target version changed from 3.3.2 to 3.3.3

Updated by Wim Dumon over 8 years ago

  • Status changed from InProgress to Feedback

Well spot, I learned today about Windows' signal handling :-)

My conclusion: Wt's waitForShutdown is a generic method, which is in many cases doing what you want. But I can imagine very well that you don't want your application to terminate without cleanup on the 'special signals' CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT.

My recommendation to you, is not to use Wt's waitForShutdown() since you want to handle the special signals in a special way, but to write your own. We can never know when your application cleaned up its state, at most we could know when all WServer objects are deleted (but we currently don't maintain a list). Any solution we would come up with, would not work for a certain use case.

Does this make sense?



Updated by Eivind Midtgård over 8 years ago

Hi Wim,

I'll try that. I had hoped that you could use my code as a starting point. (I would have tried reimplementing your waitForShutdown myself, but so far I have not been able to compile Wt with CMake, and each time I have tried compiling other systems with CMake something has gone wrong, so I have given up on CMake: I now pretend it doesn't exist. Maybe I should try once more.)

There is one thing I need to know: In your console_ctrl_handler you do this:

    boost::mutex::scoped_lock terminationLock(terminationMutex);
    terminationRequested = true;
    terminationCondition.notify_all(); // should be just 1

Is that something that my code has to do? If so, I believe it will be necessary to add a function to Wt that user-written 'waitForShutdown' functions will have to call when they have finished waiting, so that you have a place to put Wt cleanup code. Also, I wonder if implementing a shutdown function myself will interfere with WRun, which calls your waitForShutdown. I don't use WRun, but it is a pity if all Windows users will have to implement their own waitForShutdown.




Updated by Wim Dumon over 8 years ago

Hi Eivind,

Wt's waitForShutdown() really simply blocks until ctrl-c has been pressed. It uses a boost mutex and a boost condition variable to transfer the event from the console_ctrl_handler to the thread that is blocked by waitForShutdown().

With respect to WRun, you don't have to use Wt's WRun. The documentation of WRun shows you its implementation. Copy-paste that in your project, and replace waitForShutdown() with your version of waitForShutdown().

What I could do, is add a sleep of e.g. 5 seconds at the end of console_ctrl_handler(). Is my assumption correct that if main() exits, this thread will be terminated too? That would then mean that the default waitForShutdown() would give the application at most a few seconds to terminate cleanly. If your application needs more time, you'd have to write your own.




Updated by Koen Deforche over 8 years ago

  • Target version changed from 3.3.3 to 3.3.4

Also available in: Atom PDF