I'm trying to debug an issue related to a manifold that's somehow associated to an object that's gone out of scope. Since I built deal.II with threads enabled, there's no mechanism to work out which object this manifold is stubbornly attached to. Is there any technical reason as to why the list_subscribers() function of the Subscriptor class cannot be made to work with threads? I was thinking about changing its implementation from
void Subscriptor::list_subscribers () const
{
#ifndef DEAL_II_WITH_THREADS
for (map_iterator it = counter_map.begin();
it != counter_map.end(); ++it)
deallog << it->second << '/'
<< counter << " subscriptions from \""
<< it->first << '\"' << std::endl;
#else
deallog << "No subscriber listing with multithreading" << std::endl;
#endif
}
to
void Subscriptor::list_subscribers () const
{
#ifdef DEAL_II_WITH_THREADS
static std::mutex mutex;
std::lock_guard<std::mutex> lock(mutex);
#endif
for (map_iterator it = counter_map.begin();
it != counter_map.end(); ++it)
deallog << it->second << '/'
<< counter << " subscriptions from \""
<< it->first << '\"' << std::endl;
}
or, even better, implement the above in a more general function
template <typename StreamType>
void
Subscriptor::list_subscribers(StreamType &stream) const
?
I do not see any reason to disable this when threads are present; I am not aware of any place in the library where subscription is performance critical, so adding a lock or atomics should not have a noticeable effect.
The original commit for this feature (819cf4f42840c28eaebac77939e887f2333ab9aa) adds it without comment; I suspect the original author just made the (justifiable) conservative choice that its not clear how to do things with threads safely so this optional feature should be disabled.
The problem here is not reading, but writing. Your std::mutex must in fact live in Subscriptor and be also locked (std::lock_guard) when counter_map is modified in subscribe and unsubscribe.
Hmm... I see. Thanks a lot for the info and tips, @drwells and @masterleinad. I'm going to play around with this a bit more and I'll report back when I've done so...
Most helpful comment
The problem here is not reading, but writing. Your
std::mutexmust in fact live inSubscriptorand be also locked (std::lock_guard) whencounter_mapis modified insubscribeandunsubscribe.