Modified PosixThreadFactory
        Added explicit detached getter and setter
Modified PosixThreadFactory::~PThread:
        Check for join failing and don't transition to detached_ state if it does.  Potential thread-handle leak for
        threads created joinable who aren't referenced by any external thread.  Solution for now has to be
        "DONT DO THAT", the clever approach doesn't always work.

Added ThreadFactoryTests.floodNThreads:
        Loop M times for N threads where M x N is bigger than 32K to verify that detached threads can be created
        ad infinitum.

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@665130 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/concurrency/PosixThreadFactory.cpp b/lib/cpp/src/concurrency/PosixThreadFactory.cpp
index 2e8ed47..73aba61 100644
--- a/lib/cpp/src/concurrency/PosixThreadFactory.cpp
+++ b/lib/cpp/src/concurrency/PosixThreadFactory.cpp
@@ -63,13 +63,13 @@
 
   ~PthreadThread() {
     /* Nothing references this thread, if is is not detached, do a join
-       now, otherwise the thread-id and, possibly, other resources will 
+       now, otherwise the thread-id and, possibly, other resources will
        be leaked. */
     if(!detached_) {
       try {
         join();
       } catch(...) {
-        // We're really hosed. 
+        // We're really hosed.
       }
     }
   }
@@ -84,9 +84,9 @@
         throw SystemResourceException("pthread_attr_init failed");
     }
 
-    if(pthread_attr_setdetachstate(&thread_attr, 
-                                   detached_ ? 
-                                   PTHREAD_CREATE_DETACHED : 
+    if(pthread_attr_setdetachstate(&thread_attr,
+                                   detached_ ?
+                                   PTHREAD_CREATE_DETACHED :
                                    PTHREAD_CREATE_JOINABLE) != 0) {
         throw SystemResourceException("pthread_attr_setdetachstate failed");
     }
@@ -123,12 +123,18 @@
   void join() {
     if (!detached_ && state_ != uninitialized) {
       void* ignore;
-      pthread_join(pthread_, &ignore);
-      detached_ = true;
+      /* XXX
+         If join fails it is most likely due to the fact
+         that the last reference was the thread itself and cannot
+         join.  This results in leaked threads and will eventually
+         cause the process to run out of thread resources.
+         We're beyond the point of throwing an exception.  Not clear how
+         best to handle this. */
+      detached_ = pthread_join(pthread_, &ignore) == 0;
     }
   }
 
-  id_t id() {
+  id_t getId() {
     return static_cast<id_t>(pthread_);
   }
 
@@ -234,13 +240,11 @@
     return result;
   }
 
-  int stackSize() const { return stackSize_; }
+  int getStackSize() const { return stackSize_; }
 
-  void stackSize(int value) { stackSize_ = value; }
+  void setStackSize(int value) { stackSize_ = value; }
 
-  PRIORITY priority() const { return priority_; }
-
-  Thread::id_t currentThreadId() const {return static_cast<id_t>(pthread_self());}
+  PRIORITY getPriority() const { return priority_; }
 
   /**
    * Sets priority.
@@ -248,7 +252,14 @@
    *  XXX
    *  Need to handle incremental priorities properly.
    */
-  void priority(PRIORITY value) { priority_ = value; }
+  void setPriority(PRIORITY value) { priority_ = value; }
+
+  bool isDetached() const { return detached_; }
+
+  void setDetached(bool value) { detached_ = value; }
+
+  Thread::id_t getCurrentThreadId() const {return static_cast<id_t>(pthread_self());}
+
 };
 
 PosixThreadFactory::PosixThreadFactory(POLICY policy, PRIORITY priority, int stackSize, bool detached) :
@@ -256,14 +267,18 @@
 
 shared_ptr<Thread> PosixThreadFactory::newThread(shared_ptr<Runnable> runnable) const { return impl_->newThread(runnable); }
 
-int PosixThreadFactory::stackSize() const { return impl_->stackSize(); }
+int PosixThreadFactory::getStackSize() const { return impl_->getStackSize(); }
 
-void PosixThreadFactory::stackSize(int value) { impl_->stackSize(value); }
+void PosixThreadFactory::setStackSize(int value) { impl_->setStackSize(value); }
 
-PosixThreadFactory::PRIORITY PosixThreadFactory::priority() const { return impl_->priority(); }
+PosixThreadFactory::PRIORITY PosixThreadFactory::getPriority() const { return impl_->getPriority(); }
 
-void PosixThreadFactory::priority(PosixThreadFactory::PRIORITY value) { impl_->priority(value); }
+void PosixThreadFactory::setPriority(PosixThreadFactory::PRIORITY value) { impl_->setPriority(value); }
 
-Thread::id_t PosixThreadFactory::currentThreadId() const { return impl_->currentThreadId(); }
+bool PosixThreadFactory::isDetached() const { return impl_->isDetached(); }
+
+void PosixThreadFactory::setDetached(bool value) { impl_->setDetached(value); }
+
+Thread::id_t PosixThreadFactory::getCurrentThreadId() const { return impl_->getCurrentThreadId(); }
 
 }}} // facebook::thrift::concurrency