As stated in http://en.cppreference.com/w/cpp/error/terminate there are many reasons to call terminate. I can imagine case where just almost in the same time some of these reasons happen in two threads.
Q1 Can the terminate function set by std::set_terminate
be called twice or more at the same time, by the same time I mean second call begins before first has ended.
Thread1 Thread2
| |
_ |
t |
e |
r |
m |
i _
n t
a e
t r
e m
- ?
Q2 If Q1==YES, then what happens if first terminate ended. I guess if it ended with std::abort, then program ends, but what happens if user provided terminate does not abort program?
Q3 Is the terminate function set by std::set_terminate
called in context of the thread which caused this terminate call?
Thread safety A threadsafe function protects shared resources from concurrent access by locks. Thread safety concerns only the implementation of a function and does not affect its external interface. The use of global data is thread-unsafe.
This can be fixed by adding a mutex that demands that two threads cannot run the run member simultaneously. See Boost. Thread for a good mutex example. Please include an example to clarify that a const (read-only) function also needs mutex protection if another function may write to the data member at the same time.
Q1
Yes, std::terminate
can be called concurrently.
Q2
The standard says it is undefined behavior for a terminate_handler
to not "terminate execution of the program without returning to the caller". In implementations I'm familiar with, if the terminate_handler
attempts to return, either normally, or exceptionally, abort()
will be called.
Q3
The function set by std::terminate
is a global, not a thread local. So one thread can impact another.
In C++98/03, the terminate_handler
used when terminate
is called due to an uncaught exception is the one that was in effect when the exception was thrown, not the one in effect when terminate
is actually called (though they are usually the same).
In C++11 this was changed and the standard now says that the handler used is the one in place at the time terminate
is called. This change was done by mistake and will most likely be corrected in a future draft. Here is the LWG issue tracking this issue:
http://cplusplus.github.com/LWG/lwg-active.html#2111
Update
At the Spring 2015 meeting in Lenexa, KS, the LWG decided to standardize existing behavior and made it unspecified when a new terminate_handler
goes into effect if set_terminate
is called during stack unwinding. I.e. implementations are allowed to follow either the C++98/03 rules or the C++11 rules.
To make your code portable, if you need to set a terminate_handler
, do so during program startup, before any exceptions will be thrown, and do not make a habit of calling set_terminate
after that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With