Buğra Gedik created THRIFT-3932:
-----------------------------------

             Summary: C++ ThreadManager has a rare termination race
                 Key: THRIFT-3932
                 URL: https://issues.apache.org/jira/browse/THRIFT-3932
             Project: Thrift
          Issue Type: Bug
            Reporter: Buğra Gedik
         Attachments: thrift-patch

{{ThreadManger::join}} calls {{stopImpl(true)}}, which in term calls 
{{removeWorker(workerCount_);}}. The latter waits until {{while (workerCount_ 
!= workerMaxCount_)}}. In the run method, the last thread that detects 
{{workerCount_ == workerMaxCount_}} notifies the {{removeWorker}} method. 
However, the run method has the following additional code that is executed at 
the very end:

{code}
{
      Synchronized s(manager_->workerMonitor_);
      manager_->deadWorkers_.insert(this->thread());
      if (notifyManager) {
        manager_->workerMonitor_.notify();
      }
    }
{code}

This is an independent synchronized block. Now assume 2 threads. One of them 
has {{notifyManager=true}} as it detected the {{workerCount_ == 
workerMaxCount_}} condition earlier. It is possible that this thread gets to 
execute  the above code first, and the ThreadManager's {{removeWorker}} method 
unblocks and eventually the ThreadManager's {{join}} returns and the object 
destructed. When the other thread reaches the synchronized block above, it will 
crash, as the manager is not around anymore.

Besides, the ThreadManager never joins its threads.

Attached is a small fix that alleviates the problem.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to