Steven Watanabe <watanabesj@gmail.com> wrote:


You have a race condition in your destructor.
pthread_cancel, does *not* wait for the thread
to terminate. You need to join the threads
before the queue is destroyed.

It's funny and actualy quite often - while I was writing response to this quotation I found a bug, thank you! So I was about to write: "The race is only between cancellation point after sem_wait() call and manager->m_results.pop() in WorkerThreadManager::WorkerThread(), and my example uses sleep to be "sure" that WorkerThreadManager destruction occurs when A::Fun() is during sleep, so there is no access to queue". And the bug is trivial: I do pop() on an empty queue, I inteded to do it on m_tasks instead of m_results...
 
But why this bug caused crash when queue was being destructed?
 
Before I fixed this bug I also tried joining threads after cancellation, but it caused pthread_join to hang on a thread that was during task execution. Why did it happen? I use deferred cancellation so thread should be gently cancelled on sleep() which is a cancellation point.
 
Regards
Marcin Adamski