THRIFT-3974: fix ThreadSanitizer identified issues
Client: C++
This closes #1331
diff --git a/lib/cpp/src/thrift/concurrency/PosixThreadFactory.cpp b/lib/cpp/src/thrift/concurrency/PosixThreadFactory.cpp
index 6bf043b..d829d69 100644
--- a/lib/cpp/src/thrift/concurrency/PosixThreadFactory.cpp
+++ b/lib/cpp/src/thrift/concurrency/PosixThreadFactory.cpp
@@ -19,8 +19,9 @@
#include <thrift/thrift-config.h>
-#include <thrift/concurrency/PosixThreadFactory.h>
#include <thrift/concurrency/Exception.h>
+#include <thrift/concurrency/Mutex.h>
+#include <thrift/concurrency/PosixThreadFactory.h>
#if GOOGLE_PERFTOOLS_REGISTER_THREAD
#include <google/profiler.h>
@@ -52,6 +53,7 @@
private:
pthread_t pthread_;
+ Mutex state_mutex_;
STATE state_;
int policy_;
int priority_;
@@ -70,7 +72,6 @@
#ifndef _WIN32
pthread_(0),
#endif // _WIN32
-
state_(uninitialized),
policy_(policy),
priority_(priority),
@@ -93,8 +94,20 @@
}
}
+ STATE getState() const
+ {
+ Guard g(state_mutex_);
+ return state_;
+ }
+
+ void setState(STATE newState)
+ {
+ Guard g(state_mutex_);
+ state_ = newState;
+ }
+
void start() {
- if (state_ != uninitialized) {
+ if (getState() != uninitialized) {
return;
}
@@ -139,7 +152,7 @@
stdcxx::shared_ptr<PthreadThread>* selfRef = new stdcxx::shared_ptr<PthreadThread>();
*selfRef = self_.lock();
- state_ = starting;
+ setState(starting);
if (pthread_create(&pthread_, &thread_attr, threadMain, (void*)selfRef) != 0) {
throw SystemResourceException("pthread_create failed");
@@ -147,7 +160,7 @@
}
void join() {
- if (!detached_ && state_ != uninitialized) {
+ if (!detached_ && getState() != uninitialized) {
void* ignore;
/* XXX
If join fails it is most likely due to the fact
@@ -193,7 +206,7 @@
return (void*)0;
}
- if (thread->state_ != starting) {
+ if (thread->getState() != starting) {
return (void*)0;
}
@@ -201,10 +214,13 @@
ProfilerRegisterThread();
#endif
- thread->state_ = started;
+ thread->setState(started);
+
thread->runnable()->run();
- if (thread->state_ != stopping && thread->state_ != stopped) {
- thread->state_ = stopping;
+
+ STATE _s = thread->getState();
+ if (_s != stopping && _s != stopped) {
+ thread->setState(stopping);
}
return (void*)0;
diff --git a/lib/cpp/src/thrift/transport/TFileTransport.h b/lib/cpp/src/thrift/transport/TFileTransport.h
index 1167497..d6da436 100644
--- a/lib/cpp/src/thrift/transport/TFileTransport.h
+++ b/lib/cpp/src/thrift/transport/TFileTransport.h
@@ -348,7 +348,7 @@
// conditions used to block when the buffer is full or empty
Monitor notFull_, notEmpty_;
- bool closing_;
+ boost::atomic<bool> closing_;
// To keep track of whether the buffer has been flushed
Monitor flushed_;
diff --git a/lib/cpp/test/TServerIntegrationTest.cpp b/lib/cpp/test/TServerIntegrationTest.cpp
index a6e02f1..12657d4 100644
--- a/lib/cpp/test/TServerIntegrationTest.cpp
+++ b/lib/cpp/test/TServerIntegrationTest.cpp
@@ -320,7 +320,7 @@
shared_ptr<TServerType> pServer;
shared_ptr<TServerReadyEventHandler> pEventHandler;
shared_ptr<boost::thread> pServerThread;
- bool bStressDone;
+ boost::atomic<bool> bStressDone;
boost::atomic_int64_t bStressConnectionCount;
boost::atomic_int64_t bStressRequestCount;
};