For some multithreaded code, I would like to capture all exceptions and pass a them to a single exception handling thread. Here’s the message passing framework:
#include <exception>
struct message
{
virtual ~message() = default;
virtual void act() = 0;
};
struct exception_message : message
{
std::exception_ptr ep;
virtual void act()
{
std::rethrow_exception(ep);
}
// ...
};
Here’s the use case:
try
{
// ...
}
catch (...)
{
exception_message em { std::current_exception(); }
handler_thread.post_message(em);
}
The handler thread goes through all its messages and calls act(), and it can install its own try/catch block to handle all the posted exceptions.
Now I was wondering what happens if I send copies this message to multiple receivers. In general, messages may have any number of recipients, and so I don’t want to put arbitrary restrictions on exception propagation messages. The exception_ptr is documented as a “shared-ownership” smart pointer, and rethrow_exception “does not introduce a data race”.
So my question: Is it legitimate to duplicate an active exception by storing it in an exception_ptr, copying the pointer, and calling rethrow_exception multiple times?
From my understanding of the Standard, it is legitimate. However I would note that the rethrow does not duplicate the exception, and therefore the shared exception object itself is submitted to data races should you modify it and access it from other threads meantime. If the exception is read-only (once thrown), then you should not have any issue.
Regarding storage duration:
Regarding data races:
Regarding
rethrow: