Context:
I'm working with with a project composed simplistically of three layers, an application layer, an interface layer, and a middleware layer. The interface layer provides additional functionality on top of the middleware layer, and is responsible for managing threads running the middleware application.
My issue is that to exit the program, interrupt signals are used, the handler for these signals is defined at the lowest, middleware layer. When an interrupt signal is sent, the handler eventually calls exit(0)
, which results in an interface-layer destructor being called by the same thread calling exit(0)
. Within this destructor, middlewareAppThread.join()
is called, resulting in a deadlock as the thread is trying to join itself.
This is a simplified representation, sorry if it's messy:
What confuses me is seeing how the Proxy object is referenced in the global namespace, I thought the destructor would be called by the main thread, but when debugging it's apparent the destructor is called by middlewareAppThread
.
The solution I've thought of so far is to remove the signal handler from the middleware stack, and create one in the app/interface layer. This is a little problematic as the middleware is third-party. Is there a way to keep the exit(0)
call at the lowest level, with the destructors being called from the main thread?
Or: What could be causing the destructor to be called from the middlewareAppThread
?
CodePudding user response:
It is the thread that calls exit
that does all of the cleanup.
Several cleanup steps are performed:
- The destructors of objects with thread local storage duration that are associated with the current thread, the destructors of objects with static storage duration, and the functions registered with std::atexit are executed concurrently
(emphasis added)
I thought the destructor would be called by the main thread
What makes you think that? C does not associate objects with threads. Even a thread local object can be interacted with on another thread through a pointer or reference.
Is there a way to keep the
exit(0)
call at the lowest level
Yes, don't have static duration std::thread
(sub-)objects, especially those which can call exit
.
with the destructors being called from the main thread?
Co-ordinate such that the main thread is the one to call exit
. Or just return from main