diff options
author | Michi Henning <michi@zeroc.com> | 2002-11-29 01:18:03 +0000 |
---|---|---|
committer | Michi Henning <michi@zeroc.com> | 2002-11-29 01:18:03 +0000 |
commit | 404a9441f45ac9ca1ba39f04c7f8d1f9fc79de5b (patch) | |
tree | 12023d167f8ab1b161aaec017a206863f4888bbf /cpp | |
parent | fixing potential deadlock with ObjectAdapter (diff) | |
download | ice-404a9441f45ac9ca1ba39f04c7f8d1f9fc79de5b.tar.bz2 ice-404a9441f45ac9ca1ba39f04c7f8d1f9fc79de5b.tar.xz ice-404a9441f45ac9ca1ba39f04c7f8d1f9fc79de5b.zip |
Added ThreadControl::detach().
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/include/IceUtil/Thread.h | 9 | ||||
-rw-r--r-- | cpp/src/IceUtil/Thread.cpp | 34 | ||||
-rw-r--r-- | cpp/test/IceUtil/thread/DetachTest.cpp | 97 | ||||
-rw-r--r-- | cpp/test/IceUtil/thread/DetachTest.h | 31 | ||||
-rw-r--r-- | cpp/test/IceUtil/thread/Makefile | 1 | ||||
-rw-r--r-- | cpp/test/IceUtil/thread/TestSuite.cpp | 2 |
6 files changed, 173 insertions, 1 deletions
diff --git a/cpp/include/IceUtil/Thread.h b/cpp/include/IceUtil/Thread.h index f9d954dee95..b7ffea27c9e 100644 --- a/cpp/include/IceUtil/Thread.h +++ b/cpp/include/IceUtil/Thread.h @@ -73,6 +73,14 @@ public: // void join(); + // + // Detach a thread. Once a thread is detached, it cannot be detached + // again, nor can it be joined with. Every thread must either be + // joined with or detached exactly once. Failing to do so results + // in resource leaks. + // + void detach(); + static void sleep(const Time&); static void yield(); @@ -81,6 +89,7 @@ private: #ifdef _WIN32 HandleWrapperPtr _handle; unsigned _id; + bool _detached; #else pthread_t _id; #endif diff --git a/cpp/src/IceUtil/Thread.cpp b/cpp/src/IceUtil/Thread.cpp index 41e96cc1ac7..86cb499cb5b 100644 --- a/cpp/src/IceUtil/Thread.cpp +++ b/cpp/src/IceUtil/Thread.cpp @@ -35,7 +35,8 @@ IceUtil::ThreadControl::ThreadControl() : IceUtil::ThreadControl::ThreadControl(const HandleWrapperPtr& handle, unsigned id) : _handle(handle), - _id(id) + _id(id), + _detached(false) { } @@ -62,6 +63,11 @@ IceUtil::ThreadControl::join() { if(_handle->handle) { + if (_detached) + { + throw ThreadSyscallException(__FILE__, __LINE__); + } + _detached = true; int rc = WaitForSingleObject(_handle->handle, INFINITE); if(rc != WAIT_OBJECT_0) { @@ -71,6 +77,19 @@ IceUtil::ThreadControl::join() } void +IceUtil::ThreadControl::detach() +{ + if(_handle->handle) + { + if (_detached) + { + throw ThreadSyscallException(__FILE__, __LINE__); + } + _detached = true; + } +} + +void IceUtil::ThreadControl::sleep(const Time& timeout) { timeval tv = timeout; @@ -228,6 +247,19 @@ IceUtil::ThreadControl::join() } void +IceUtil::ThreadControl::detach() +{ + if(_id) + { + int rc = pthread_detach(_id); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__); + } + } +} + +void IceUtil::ThreadControl::sleep(const Time& timeout) { struct timeval tv = timeout; diff --git a/cpp/test/IceUtil/thread/DetachTest.cpp b/cpp/test/IceUtil/thread/DetachTest.cpp new file mode 100644 index 00000000000..bd7a5499f99 --- /dev/null +++ b/cpp/test/IceUtil/thread/DetachTest.cpp @@ -0,0 +1,97 @@ +// ********************************************************************** +// +// Copyright (c) 2002 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#include <IceUtil/IceUtil.h> + +#include <stdio.h> + +#include <DetachTest.h> +#include <TestCommon.h> + +using namespace std; +using namespace IceUtil; + +static const string createTestName("thread detach"); + +class DetachTestThread : public Thread +{ +public: + + DetachTestThread() + { + } + + virtual void run() + { + } +}; + +typedef Handle<DetachTestThread> DetachTestThreadPtr; + +DetachTest::DetachTest() : + TestBase(createTestName) +{ +} + +void +DetachTest::run() +{ + // + // Check that calling join() more than once raises ThreadSyscallException. + // + DetachTestThreadPtr t = new DetachTestThread(); + ThreadControl control = t->start(); + control.join(); + bool gotException = false; + try { + control.join(); + } + catch(const ThreadSyscallException&) + { + gotException = true; + } + test(gotException); + + // + // Check that calling detach() more than once raises ThreadSyscallException. + // + t = new DetachTestThread(); + control = t->start(); + control.detach(); + gotException = false; + try { + control.detach(); + } + catch(const ThreadSyscallException&) + { + gotException = true; + } + test(gotException); + + // + // Check that calling join() after detach() raises ThreadSyscallException. + // + t = new DetachTestThread(); + control = t->start(); + control.detach(); + gotException = false; + try { + control.join(); + } + catch(const ThreadSyscallException&) + { + gotException = true; + } + test(gotException); +} diff --git a/cpp/test/IceUtil/thread/DetachTest.h b/cpp/test/IceUtil/thread/DetachTest.h new file mode 100644 index 00000000000..b7b844ad9b4 --- /dev/null +++ b/cpp/test/IceUtil/thread/DetachTest.h @@ -0,0 +1,31 @@ +// ********************************************************************** +// +// Copyright (c) 2002 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifndef DETACH_TEST_H +#define DETACH_TEST_H + +#include <TestBase.h> + +class DetachTest : public TestBase +{ +public: + + DetachTest(); + +private: + + virtual void run(); +}; + +#endif diff --git a/cpp/test/IceUtil/thread/Makefile b/cpp/test/IceUtil/thread/Makefile index 6beeb239e7c..ad5fa17752b 100644 --- a/cpp/test/IceUtil/thread/Makefile +++ b/cpp/test/IceUtil/thread/Makefile @@ -20,6 +20,7 @@ TARGETS = $(CLIENT) OBJS = TestBase.o \ CreateTest.o \ + DetachTest.o \ RWRecMutexTest.o \ RecMutexTest.o \ MutexTest.o \ diff --git a/cpp/test/IceUtil/thread/TestSuite.cpp b/cpp/test/IceUtil/thread/TestSuite.cpp index 582509f9c9f..09d4e82fff6 100644 --- a/cpp/test/IceUtil/thread/TestSuite.cpp +++ b/cpp/test/IceUtil/thread/TestSuite.cpp @@ -17,6 +17,7 @@ #include <RecMutexTest.h> #include <RWRecMutexTest.h> #include <CreateTest.h> +#include <DetachTest.h> #include <MonitorMutexTest.h> #include <MonitorRecMutexTest.h> @@ -26,6 +27,7 @@ void initializeTestSuite() { allTests.push_back(new CreateTest); + allTests.push_back(new DetachTest); allTests.push_back(new MutexTest); allTests.push_back(new RecMutexTest); allTests.push_back(new RWRecMutexTest); |