GH #79: Poco::Thread leak on Linux

fixed GH #79: Poco::Thread leak on Linux
This commit is contained in:
Alex
2013-03-17 21:13:04 -05:00
parent 3d16ce00a2
commit 3efbbdc1f7
5 changed files with 52 additions and 6 deletions

View File

@@ -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)
==========================

View File

@@ -155,7 +155,8 @@ private:
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 @@ private:
int policy;
Event done;
std::size_t stackSize;
bool joined;
};
AutoPtr<ThreadData> _pData;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -51,6 +51,7 @@ public:
void testCurrent();
void testThreads();
void testJoin();
void testNotJoin();
void testThreadTarget();
void testThreadFunction();
void testThreadStackSize();