diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2016-12-01 12:35:36 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2016-12-01 12:35:36 +0100 |
commit | d36b3bcb7e08f7f73709b7afe9b8f9ec22a0fcd2 (patch) | |
tree | e1af3d7ae5bce5f8e658a81c966d09ed3d40578d /comphelper | |
parent | 659210773abff4dd4a5937c7995af5c0981e9020 (diff) |
Fix race in ThreadTaskTag
Assume T0 calls ThreadPool::pushTask twice, then ThreadPool::waitUntilDone:
T0 calls ThreadTaskTag::onTaskPushed:
mnTasksWorking = 1, maTasksComplete.reset
T1 runs the 1st task to completion and calls ThreadTaskTag::onTaskWorkerDone:
mnTasksWorking = 0; suspended...
T0 calls ThreadTaskTag::onTaskPushed:
mnTaskWorking = 1, maTasksComplete.reset
T1 continues in the call to ThreadTaskTag::onTaskWorkerDone:
..., maTasksComplete.set
T0 calls ThreadTaskTag::waitUntilDone and immediately returns
T2 only now starts to run the 2nd task
Change-Id: Ic29101a4791fca2a1a4d54b559f10ff706e8a20d
Diffstat (limited to 'comphelper')
-rw-r--r-- | comphelper/source/misc/threadpool.cxx | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/comphelper/source/misc/threadpool.cxx b/comphelper/source/misc/threadpool.cxx index 346c1712b270..0fda2646b7f1 100644 --- a/comphelper/source/misc/threadpool.cxx +++ b/comphelper/source/misc/threadpool.cxx @@ -26,8 +26,9 @@ static thread_local bool gbIsWorkerThread; // used to group thread-tasks for waiting in waitTillDone() class COMPHELPER_DLLPUBLIC ThreadTaskTag { - oslInterlockedCount mnTasksWorking; - osl::Condition maTasksComplete; + osl::Mutex mMutex; + std::size_t mnTasksWorking; + osl::Condition maTasksComplete; public: ThreadTaskTag(); @@ -302,17 +303,18 @@ ThreadTaskTag::ThreadTaskTag() : mnTasksWorking(0) void ThreadTaskTag::onTaskPushed() { - oslInterlockedCount n = osl_atomic_increment(&mnTasksWorking); - assert( n < 65536 ); // sanity checking - (void)n; // avoid -Wunused-variable in release build + osl::MutexGuard g(mMutex); + assert( mnTasksWorking < 65535 ); // sanity checking + ++mnTasksWorking; maTasksComplete.reset(); } void ThreadTaskTag::onTaskWorkerDone() { - sal_Int32 nCount = osl_atomic_decrement(&mnTasksWorking); - assert(nCount >= 0); - if (nCount == 0) + osl::MutexGuard g(mMutex); + assert(mnTasksWorking > 0); + --mnTasksWorking; + if (mnTasksWorking == 0) maTasksComplete.set(); } |