Added thread factory test - problems in thread

Fixed stupid typo in  TimerManager::start


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664723 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/concurrency/test/Tests.cc b/lib/cpp/src/concurrency/test/Tests.cc
new file mode 100644
index 0000000..36f29ff
--- /dev/null
+++ b/lib/cpp/src/concurrency/test/Tests.cc
@@ -0,0 +1,52 @@
+#include <iostream>
+#include <string>
+
+#include "ThreadFactoryTests.h"
+#include "TimerManagerTests.h"
+
+int main(int argc, char** argv) {
+
+  std::string arg;
+
+  if(argc < 2) {
+
+    arg = "all";
+
+  } else {
+    
+    arg = std::string(argv[1]);
+  }
+
+  bool runAll = arg.compare("all") == 0;
+
+  if(runAll || arg.compare("thread-factory") == 0) {
+
+    ThreadFactoryTests threadFactoryTests;
+    
+    std::cout << "ThreadFactory tests..." << std::endl;
+    
+    std::cout << "\tThreadFactory hello-world test" << std::endl;
+
+    assert(threadFactoryTests.helloWorldTest());
+
+    std::cout << "\t\tThreadFactory reap N threads test: N = 100" << std::endl;
+
+    assert(threadFactoryTests.reapNThreads(100));
+
+    std::cout << "\t\tThreadFactory synchrous start test" << std::endl;
+
+    assert(threadFactoryTests.synchStartTest());
+  }
+
+  if(runAll || arg.compare("timer-manager") == 0) {
+
+    std::cout << "TimerManager tests..." << std::endl;
+
+    std::cout << "\t\tTimerManager test00" << std::endl;
+
+    TimerManagerTests timerManagerTests;
+
+    assert(timerManagerTests.test00());
+  }
+}
+
diff --git a/lib/cpp/src/concurrency/test/ThreadFactoryTests.h b/lib/cpp/src/concurrency/test/ThreadFactoryTests.h
new file mode 100644
index 0000000..0d93564
--- /dev/null
+++ b/lib/cpp/src/concurrency/test/ThreadFactoryTests.h
@@ -0,0 +1,228 @@
+#include <Thread.h>
+#include <PosixThreadFactory.h>
+#include <Monitor.h>
+
+#include <assert.h>
+#include <iostream>
+#include <set>
+
+namespace facebook { namespace thrift { namespace concurrency { namespace test {
+
+using namespace facebook::thrift::concurrency;
+
+/** ThreadManagerTests class 
+
+    @author marc
+    @version $Id:$ */
+
+class ThreadFactoryTests {
+
+ class Task: public Runnable {
+
+  public:
+
+    Task() {}
+
+    void run() {
+      std::cout << "\t\t\tHello World" << std::endl;
+    }
+  };
+
+public:
+
+  /** Hello world test */
+
+  bool helloWorldTest() {
+
+    PosixThreadFactory threadFactory =  PosixThreadFactory();
+
+    Task* task = new ThreadFactoryTests::Task();
+
+    Thread* thread = threadFactory.newThread(task);
+
+    thread->start();
+
+    thread->join();
+
+    delete thread;
+
+    delete task;
+
+    std::cout << "\t\t\tSuccess!" << std::endl;
+
+    return true;
+  }
+
+  /** Reap N threads  */
+
+ class ReapNTask: public Runnable {
+
+  public:
+
+  ReapNTask(Monitor& monitor, int& activeCount) :
+    _monitor(monitor),
+      _count(activeCount) {
+      }
+    
+    void run() {
+
+      {Synchronized s(_monitor);
+
+	_count--;
+
+	//std::cout << "\t\t\tthread count: " << _count << std::endl;
+
+	if(_count == 0) {
+	  _monitor.notify();
+	}
+      }
+    }
+
+    Monitor& _monitor;
+
+    int& _count;
+  };
+
+  bool reapNThreads(int count=100) {
+
+    Monitor* monitor = new Monitor();
+
+    int* activeCount  = new int(count);
+
+    PosixThreadFactory threadFactory =  PosixThreadFactory();
+
+    std::set<Thread*> threads;
+
+    for(int ix = 0; ix < count; ix++) {
+      threads.insert(threadFactory.newThread(new ReapNTask(*monitor, *activeCount)));
+    }
+
+    for(std::set<Thread*>::const_iterator thread = threads.begin(); thread != threads.end(); thread++) {
+
+      (*thread)->start();
+    }
+
+
+    {Synchronized s(*monitor);
+
+      while(*activeCount > 0) {
+	monitor->wait(1000);
+      }
+    }
+
+    for(std::set<Thread*>::const_iterator thread = threads.begin(); thread != threads.end(); thread++) {
+
+      delete (*thread)->runnable();
+
+      delete *thread;
+    }
+
+    std::cout << "\t\t\tSuccess!" << std::endl;
+
+    return true;
+  }
+
+ class SynchStartTask: public Runnable {
+
+  public:
+
+    enum STATE {
+      UNINITIALIZED = 1000,
+      STARTING = 1001,
+      STARTED = 1002,
+      STOPPING = 1003,
+      STOPPED = 1004
+    };
+
+  SynchStartTask(Monitor& monitor,
+		 volatile  STATE& state) :
+    _monitor(monitor),
+    _state(state) {
+    }
+
+    void run() {
+
+      {Synchronized s(_monitor);
+
+	if(_state == SynchStartTask::STARTING) {
+	  _state = SynchStartTask::STARTED;
+	  _monitor.notify();
+	}
+      }
+
+      {Synchronized s(_monitor);
+	
+	while(_state == SynchStartTask::STARTED) {
+	  _monitor.wait();
+	}
+
+	if(_state == SynchStartTask::STOPPING) {
+	  
+	  _state = SynchStartTask::STOPPED;
+	  
+	  _monitor.notifyAll();
+	}
+      }
+    }
+
+    private:
+    Monitor& _monitor;
+    volatile  STATE& _state;
+  };
+
+  bool synchStartTest() {
+
+    Monitor monitor;
+    
+    SynchStartTask::STATE state = SynchStartTask::UNINITIALIZED;
+    
+    SynchStartTask* task = new SynchStartTask(monitor, state);
+
+    PosixThreadFactory threadFactory =  PosixThreadFactory();
+
+    Thread* thread = threadFactory.newThread(task);
+
+    if(state == SynchStartTask::UNINITIALIZED) {
+
+      state = SynchStartTask::STARTING;
+
+      thread->start();
+    }
+
+    {Synchronized s(monitor);
+      
+      while(state == SynchStartTask::STARTING) {
+	monitor.wait();
+      }
+    }
+
+    assert(state != SynchStartTask::STARTING);
+
+    {Synchronized s(monitor);
+
+      monitor.wait(100);
+
+      if(state == SynchStartTask::STARTED) {
+
+	state = SynchStartTask::STOPPING;
+
+	monitor.notify();
+      }
+      
+      while(state == SynchStartTask::STOPPING) {
+	monitor.wait();
+      }
+    }
+
+    assert(state == SynchStartTask::STOPPED);
+
+    return true;
+  }
+
+};
+  
+
+}}}} // facebook::thrift::concurrency
+
+using namespace facebook::thrift::concurrency::test;
+
diff --git a/lib/cpp/src/concurrency/test/TimerManagerTests.cc b/lib/cpp/src/concurrency/test/TimerManagerTests.cc
deleted file mode 100644
index abd0e95..0000000
--- a/lib/cpp/src/concurrency/test/TimerManagerTests.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <ThreadManager.h>
-#include <PosixThreadFactory.h>
-
-#include <assert.h>
-
-namespace facebook { namespace thrift { namespace concurrency { namespace test {
-
-/** ThreadManagerTests class */
-
-
-class ThreadManagerTests {
-
-  void init() {
-
-    ThreadManager* threadManager =  ThreadManager::newThreadManager();
-
-    threadManager->poolPolicy(new BasicPoolPolicy());
-
-    threadManager->threadFactory(new PosixThreadFactory());
-
-    threadManager->poolPolicy(new BasicPoolPolicy());
-  }
-};
-  
-
-}}}} // facebook::thrift::concurrency
-
-int main(int argc, char** argv) {
-
-  return 0;
-
-}
-
diff --git a/lib/cpp/src/concurrency/test/TimerManagerTests.h b/lib/cpp/src/concurrency/test/TimerManagerTests.h
new file mode 100644
index 0000000..24f7964
--- /dev/null
+++ b/lib/cpp/src/concurrency/test/TimerManagerTests.h
@@ -0,0 +1,81 @@
+#include <TimerManager.h>
+#include <PosixThreadFactory.h>
+#include <Monitor.h>
+
+#include <assert.h>
+#include <iostream>
+
+namespace facebook { namespace thrift { namespace concurrency { namespace test {
+
+using namespace facebook::thrift::concurrency;
+
+/** ThreadManagerTests class 
+
+    @author marc
+    @version $Id:$ */
+
+class TimerManagerTests {
+
+ class Task: public Runnable {
+
+  public:
+    
+  Task(Monitor& monitor) : 
+    _monitor(monitor),
+    _done(false) {}
+
+    void run() {
+
+      std::cout << "\t\t\tHello World" << std::endl;
+
+      _done = true;
+      
+      {Synchronized s(_monitor);
+	_monitor.notifyAll();
+      }
+    }
+    
+    Monitor& _monitor;
+    bool _done;
+  };
+
+public:
+
+  bool test00() {
+
+    TimerManager* timerManager =  new TimerManager();
+
+    timerManager->threadFactory(new PosixThreadFactory());
+
+    timerManager->start();
+
+    assert(timerManager->state() == TimerManager::STARTED);
+
+    TimerManagerTests::Task* task = new TimerManagerTests::Task(_monitor);
+
+    {Synchronized s(_monitor);
+
+      timerManager->add(task, 1000LL);
+
+      _monitor.wait();
+    }
+
+    assert(task->_done);
+
+    delete task;
+
+    std::cout << "\t\t\tSuccess!" << std::endl;
+
+    return true;
+  }
+
+  friend class TestTask;
+
+  Monitor _monitor;
+};
+  
+
+}}}} // facebook::thrift::concurrency
+
+using namespace facebook::thrift::concurrency::test;
+