Permalink
Browse files

GH #79: Poco::Thread leak on Linux

fixed GH #79: Poco::Thread leak on Linux
  • Loading branch information...
1 parent 3d16ce0 commit 3efbbdc1f739ddf8ddfeaf7027a923e63baae312 @aleks-f aleks-f committed Mar 18, 2013
View
@@ -29,6 +29,7 @@ Release 1.5.2 (2013-03-??)
- redefined DefaultHandler as typedef to ParseHandler
- fixed GH #127: Eliminate -Wshadow warnings
- SocketAddress small object optimization
+- fixed GH #79: Poco::Thread leak on Linux
Release 1.5.1 (2013-01-11)
==========================
@@ -155,7 +155,8 @@ class Foundation_API ThreadImpl
prio(PRIO_NORMAL_IMPL),
policy(SCHED_OTHER),
done(false),
- stackSize(POCO_THREAD_STACK_SIZE)
+ stackSize(POCO_THREAD_STACK_SIZE),
+ joined(false)
{
#if defined(POCO_VXWORKS)
// This workaround is for VxWorks 5.x where
@@ -172,6 +173,7 @@ class Foundation_API ThreadImpl
int policy;
Event done;
std::size_t stackSize;
+ bool joined;
};
AutoPtr<ThreadData> _pData;
@@ -51,7 +51,6 @@
# include <time.h>
#endif
-
//
// Block SIGPIPE in main thread.
//
@@ -114,8 +113,10 @@ ThreadImpl::ThreadImpl():
ThreadImpl::~ThreadImpl()
{
- if (isRunningImpl())
+ if (!_pData->joined)
+ {
pthread_detach(_pData->thread);
+ }
}
@@ -269,9 +270,11 @@ void ThreadImpl::startImpl(Callable target, void* pData)
{
_pData->pCallbackTarget->callback = 0;
_pData->pCallbackTarget->pData = 0;
+ pthread_attr_destroy(&attributes);
throw SystemException("cannot start thread");
}
-
+ pthread_attr_destroy(&attributes);
+
if (_pData->policy == SCHED_OTHER)
{
if (_pData->prio != PRIO_NORMAL_IMPL)
@@ -297,7 +300,8 @@ void ThreadImpl::joinImpl()
_pData->done.wait();
void* result;
if (pthread_join(_pData->thread, &result))
- throw SystemException("cannot join thread");
+ throw SystemException("cannot join thread");
+ _pData->joined = true;
}
@@ -460,7 +464,6 @@ void* ThreadImpl::callableEntry(void* pThread)
pData->pCallbackTarget->callback = 0;
pData->pCallbackTarget->pData = 0;
-
pData->done.set();
return 0;
}
@@ -112,6 +112,28 @@ void freeFunc(void* pData)
}
+class NonJoinRunnable : public Runnable
+{
+public:
+ NonJoinRunnable() : _finished(false)
+ {
+ }
+
+ void run()
+ {
+ _finished = true;
+ }
+
+ bool finished() const
+ {
+ return _finished;
+ }
+
+private:
+ bool _finished;
+};
+
+
ThreadTest::ThreadTest(const std::string& name): CppUnit::TestCase(name)
{
}
@@ -226,6 +248,22 @@ void ThreadTest::testJoin()
}
+void ThreadTest::testNotJoin()
+{
+ Thread thread;
+ NonJoinRunnable r;
+ thread.start(r);
+
+ while (!r.finished())
+ {
+ Thread::sleep(10);
+ }
+
+ Thread::sleep(100);
+ assert (!thread.isRunning());
+}
+
+
void ThreadTest::testThreadTarget()
{
ThreadTarget te(&MyRunnable::staticFunc);
@@ -335,6 +373,7 @@ CppUnit::Test* ThreadTest::suite()
CppUnit_addTest(pSuite, ThreadTest, testCurrent);
CppUnit_addTest(pSuite, ThreadTest, testThreads);
CppUnit_addTest(pSuite, ThreadTest, testJoin);
+ CppUnit_addTest(pSuite, ThreadTest, testNotJoin);
CppUnit_addTest(pSuite, ThreadTest, testThreadTarget);
CppUnit_addTest(pSuite, ThreadTest, testThreadFunction);
CppUnit_addTest(pSuite, ThreadTest, testThreadStackSize);
@@ -51,6 +51,7 @@ class ThreadTest: public CppUnit::TestCase
void testCurrent();
void testThreads();
void testJoin();
+ void testNotJoin();
void testThreadTarget();
void testThreadFunction();
void testThreadStackSize();

0 comments on commit 3efbbdc

Please sign in to comment.