2
votes

For some reason the call signal.notify_one() blocks the current thread and doesn't return. I have never heard about this behavior and I don't know how to resolve it.

{
  std::lock_guard<std::mutex> lock(_mutex);
  _exit = true; // _exit is a std::atomic<bool> 
}

std::cout << "before" << std::endl;
_signal.notify_one();
std::cout << "after" << std::endl;

_thread.join();

I'm using Microsoft Visual C++ 2015 and the code above is called during destruction.

I hope you can point me in the right direction, thank you much for your help!

2
Is the code snippet above from a callback? Can you include code that is waiting for the notification? Also, a small point, you don't need _exit to be std::atomic given that it is protected by _mutex. - GigaRohan
A call to notify_one may awaken a thread that had called _signal.wait(), which is where your code may be. Consider adding breakpoints after your _signal.wait() to see if that's where your code returns to - Tas

2 Answers

6
votes

Okey, I finally was able to find the problem. To give a bit of background, I'm currently using some Poco libraries (see http://pocoproject.org/) and I implemented my own Poco::Channel. After some digging I realized that Poco keeps all channels in a static LoggingRegistry which is only freed after all remaining threads have been killed.

My best guess is that a std::condition_variable becomes invalid if a thread is killed that is waiting on that std::condition_variable.

Anyway, in order to prevent the issue, one has to call the following before the main(int argc, char** argv) returns:

Poco::Logger::shutdown();
Poco::LoggingRegistry::defaultRegistry().clear(); 
0
votes

I encountered a similar behavior in an embedded environment. Depending on how the condition_variables are implemented in your OS, the notifying thread might implicitly wait for the notified thread.

If your notified thread has a very low priority and is blocked from running for a while, the call to notify_one() might block as well, until the system has time to schedule the low prio task.