Modified PosixThreadFactory::PThread:
Pay attention to detached flags. If thread is create non-detached and has not been joined when all references are given up,
(ie boost::share_ptr calls ~PThread) do the join in the destructor to prevent thread ids from being leaked.
Modified ThreadFactoryTests.reapNThreads:
Loop M times for M threads where M x N is bigger than 32K to verify that thread ids aren't leaked
Modified TimerManager.cpp:
Removed debug messages.
Reviewed By: mcslee
Revert Plan: revertible
Test Plan: concurrency_test thread-factory passes
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665129 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/concurrency/PosixThreadFactory.cpp b/lib/cpp/src/concurrency/PosixThreadFactory.cpp
index 5f86ea2..2e8ed47 100644
--- a/lib/cpp/src/concurrency/PosixThreadFactory.cpp
+++ b/lib/cpp/src/concurrency/PosixThreadFactory.cpp
@@ -46,35 +46,49 @@
int priority_;
int stackSize_;
weak_ptr<PthreadThread> self_;
+ bool detached_;
public:
- PthreadThread(int policy, int priority, int stackSize, shared_ptr<Runnable> runnable) :
+ PthreadThread(int policy, int priority, int stackSize, bool detached, shared_ptr<Runnable> runnable) :
pthread_(0),
state_(uninitialized),
policy_(policy),
priority_(priority),
- stackSize_(stackSize) {
+ stackSize_(stackSize),
+ detached_(detached) {
this->Thread::runnable(runnable);
}
- ~PthreadThread() {}
+ ~PthreadThread() {
+ /* Nothing references this thread, if is is not detached, do a join
+ now, otherwise the thread-id and, possibly, other resources will
+ be leaked. */
+ if(!detached_) {
+ try {
+ join();
+ } catch(...) {
+ // We're really hosed.
+ }
+ }
+ }
void start() {
if (state_ != uninitialized) {
return;
}
- state_ = starting;
-
pthread_attr_t thread_attr;
if (pthread_attr_init(&thread_attr) != 0) {
throw SystemResourceException("pthread_attr_init failed");
}
- if (pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE) != 0) {
- throw SystemResourceException("pthread_attr_setdetachstate failed");
+ if(pthread_attr_setdetachstate(&thread_attr,
+ detached_ ?
+ PTHREAD_CREATE_DETACHED :
+ PTHREAD_CREATE_JOINABLE) != 0) {
+ throw SystemResourceException("pthread_attr_setdetachstate failed");
}
// Set thread stack size
@@ -99,20 +113,23 @@
shared_ptr<PthreadThread>* selfRef = new shared_ptr<PthreadThread>();
*selfRef = self_.lock();
+ state_ = starting;
+
if (pthread_create(&pthread_, &thread_attr, threadMain, (void*)selfRef) != 0) {
throw SystemResourceException("pthread_create failed");
}
}
void join() {
- if (state_ != stopped) {
+ if (!detached_ && state_ != uninitialized) {
void* ignore;
pthread_join(pthread_, &ignore);
+ detached_ = true;
}
}
id_t id() {
- return pthread_;
+ return static_cast<id_t>(pthread_);
}
shared_ptr<Runnable> runnable() const { return Thread::runnable(); }
@@ -211,7 +228,7 @@
* @param runnable A runnable object
*/
shared_ptr<Thread> newThread(shared_ptr<Runnable> runnable) const {
- shared_ptr<PthreadThread> result = shared_ptr<PthreadThread>(new PthreadThread(toPthreadPolicy(policy_), toPthreadPriority(policy_, priority_), stackSize_, runnable));
+ shared_ptr<PthreadThread> result = shared_ptr<PthreadThread>(new PthreadThread(toPthreadPolicy(policy_), toPthreadPriority(policy_, priority_), stackSize_, detached_, runnable));
result->weakRef(result);
runnable->thread(result);
return result;
@@ -223,7 +240,7 @@
PRIORITY priority() const { return priority_; }
- Thread::id_t currentThreadId() const { return pthread_self(); }
+ Thread::id_t currentThreadId() const {return static_cast<id_t>(pthread_self());}
/**
* Sets priority.