简体   繁体   中英

Multithreaded object destruction on closing MFC dialog

So, this is the problem:

I have written a wrapper class exposing simplified API for the libtorrent c++ library. It (the wrapper) has a stack-allocated member, which is libtorrent's main session object. The library itself uses boost framework, and its threading features - it is multithreaded. (I must say that I'm not really familiar with boost.)

Now, I wanted to create a simple MFC dialog-based application that will have a couple of buttons for managing the session, progress bar, etc.

The destructor of a libtorrent session may take a while to finish (since it needs to notify the trackers that it's closing). The user is prompted on exit with a MessageBox to confirm download termination, so I thought it was a good idea to put my wrapper object as a member of the app class, rather than the CDialog (the wrapper destructor, and consequently the session's will kick in after the dialog is closed). Libtorrent docs also state that it is a good idea to close UI such as windows before the destructor is invoked.

And here comes the fun part - everything works fine, until I close the dialog. The process continues to live for a couple of seconds, and then crashes with some boost-related locks/critical section stuff (that's where the debugger pointed, some lock / release call in one of the boost's headers)...

EDIT
Seems that while closing, some thread checks are performed from the main window, and it gets into some "irregular" state where it does something that makes the boost fail. I'm thinking some kind of a "join" is needed for the gui thread, to wait for other threads termination...

If anyone understood what I was trying to explain here, and has some idea what am I doing wrong, or has an alternative solution to this concept, I'd really appreciate it.
Thanks.

You can wait for the Boost threads to join prior to exiting. I have an Output_Processor class that uses a Boost thread. I interface to it through a queue. Once I want to shutdown the app, I put a shutdown command in its queue. The Output_Processor thread returns after processing that command. Then my block on join returns and the rest of the app can shutdown gracefully.

...
_output_processor_queue->write(shutdown_command);

// Wait for output processor thread to join.
_output_processor_thread->join();

_output_processor_initialized = false;
...

OK, the problem is resolved.
All I did is that I initially created a dynamic wrapper object, and deleted it after doModal() returns. At that point the main thread blocks, waiting till the deletion operation is over, which is basically until the libtorrent session is destructed. However, the peculiar behavior of non-dynamic object remains.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM