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;
+