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/test/Tests.cpp b/lib/cpp/src/concurrency/test/Tests.cpp
index 5fe4651..a160472 100644
--- a/lib/cpp/src/concurrency/test/Tests.cpp
+++ b/lib/cpp/src/concurrency/test/Tests.cpp
@@ -33,11 +33,17 @@
std::cout << "ThreadFactory tests..." << std::endl;
size_t count = 1000;
+ size_t floodLoops = 1;
+ size_t floodCount = 100000;
std::cout << "\t\tThreadFactory reap N threads test: N = " << count << std::endl;
assert(threadFactoryTests.reapNThreads(count));
+ std::cout << "\t\tThreadFactory floodN threads test: N = " << floodCount << std::endl;
+
+ assert(threadFactoryTests.floodNTest(floodLoops, floodCount));
+
std::cout << "\t\tThreadFactory synchronous start test" << std::endl;
assert(threadFactoryTests.synchStartTest());
@@ -134,4 +140,3 @@
}
}
}
-
diff --git a/lib/cpp/src/concurrency/test/ThreadFactoryTests.h b/lib/cpp/src/concurrency/test/ThreadFactoryTests.h
index 4cd6bd5..99bc94e 100644
--- a/lib/cpp/src/concurrency/test/ThreadFactoryTests.h
+++ b/lib/cpp/src/concurrency/test/ThreadFactoryTests.h
@@ -112,7 +112,7 @@
throw e;
}
}
-
+
tix = 0;
for (std::set<shared_ptr<Thread> >::const_iterator thread = threads.begin(); thread != threads.end(); tix++, ++thread) {
@@ -123,14 +123,14 @@
throw e;
}
}
-
+
{
Synchronized s(*monitor);
while (*activeCount > 0) {
monitor->wait(1000);
}
}
-
+
for (std::set<shared_ptr<Thread> >::const_iterator thread = threads.begin(); thread != threads.end(); thread++) {
threads.erase(*thread);
}
@@ -276,6 +276,67 @@
return success;
}
+
+
+ class FloodTask : public Runnable {
+ public:
+
+ FloodTask(const size_t id) :_id(id) {}
+ ~FloodTask(){
+ if(_id % 1000 == 0) {
+ std::cout << "\t\tthread " << _id << " done" << std::endl;
+ }
+ }
+
+ void run(){
+ if(_id % 1000 == 0) {
+ std::cout << "\t\tthread " << _id << " started" << std::endl;
+ }
+
+ usleep(1);
+ }
+ const size_t _id;
+ };
+
+ void foo(PosixThreadFactory *tf) {
+ }
+
+ bool floodNTest(size_t loop=1, size_t count=100000) {
+
+ bool success = false;
+
+ for(size_t lix = 0; lix < loop; lix++) {
+
+ PosixThreadFactory threadFactory = PosixThreadFactory();
+ threadFactory.setDetached(true);
+
+ for(size_t tix = 0; tix < count; tix++) {
+
+ try {
+
+ shared_ptr<FloodTask> task(new FloodTask(lix * count + tix ));
+
+ shared_ptr<Thread> thread = threadFactory.newThread(task);
+
+ thread->start();
+
+ usleep(1);
+
+ } catch (TException& e) {
+
+ std::cout << "\t\t\tfailed to start " << lix * count + tix << " thread " << e.what() << std::endl;
+
+ return success;
+ }
+ }
+
+ std::cout << "\t\t\tflooded " << (lix + 1) * count << " threads" << std::endl;
+
+ success = true;
+ }
+
+ return success;
+ }
};
const double ThreadFactoryTests::ERROR = .20;
diff --git a/lib/cpp/src/concurrency/test/ThreadManagerTests.h b/lib/cpp/src/concurrency/test/ThreadManagerTests.h
index 5f518ca..a8fdcda 100644
--- a/lib/cpp/src/concurrency/test/ThreadManagerTests.h
+++ b/lib/cpp/src/concurrency/test/ThreadManagerTests.h
@@ -100,7 +100,7 @@
shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
- threadFactory->priority(PosixThreadFactory::HIGHEST);
+ threadFactory->setPriority(PosixThreadFactory::HIGHEST);
threadManager->threadFactory(threadFactory);
@@ -239,7 +239,7 @@
shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
- threadFactory->priority(PosixThreadFactory::HIGHEST);
+ threadFactory->setPriority(PosixThreadFactory::HIGHEST);
threadManager->threadFactory(threadFactory);