Index: src/xplcommon/Thread.h
===================================================================
--- src/xplcommon/Thread.h	(revision 20)
+++ src/xplcommon/Thread.h	(revision 35)
@@ -53,4 +53,14 @@
 
 public:
+    /**
+     * Construct the thread.
+     *
+     * @param detached if true, the thread will be created as a
+     * detached one, i.e. it can't be joined later on. The thread
+     * object will also be deleted when its run() function has
+     * finished.
+     */
+    Thread(bool detached = false);
+
     /**
      * Virtual destructor.
Index: src/xplcommon/posix/Thread.cc
===================================================================
--- src/xplcommon/posix/Thread.cc	(revision 3)
+++ src/xplcommon/posix/Thread.cc	(revision 35)
@@ -40,6 +40,21 @@
 void* Thread::threadFn(void* arg)
 {
-    reinterpret_cast<Thread*>(arg)->run();
+    Thread* thread = reinterpret_cast<Thread*>(arg);
+    thread->run();
+    if (thread->detached) delete thread;
     return 0;
+}
+
+//------------------------------------------------------------------------------
+
+bool Thread::start()
+{
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, detached ? PTHREAD_CREATE_DETACHED :
+                                PTHREAD_CREATE_JOINABLE);
+    bool isOK = pthread_create(&thread, &attr, &threadFn, this)>=0;
+    pthread_attr_destroy(&attr);
+    return isOK;
 }
 
Index: src/xplcommon/posix/Thread.h
===================================================================
--- src/xplcommon/posix/Thread.h	(revision 4)
+++ src/xplcommon/posix/Thread.h	(revision 35)
@@ -59,4 +59,9 @@
 
     /**
+     * Indicate if the thread is detached or not.
+     */
+    bool detached;
+
+    /**
      * The posix thread handle.
      */
@@ -64,4 +69,9 @@
 
 public:
+    /**
+     * Construct the thread
+     */
+    Thread(bool detached = false);
+
     /**
      * Virtual destructor.
@@ -98,5 +108,6 @@
 //------------------------------------------------------------------------------
 
-inline Thread::~Thread()
+inline Thread::Thread(bool detached) :
+    detached(detached)
 {
 }
@@ -104,7 +115,6 @@
 //------------------------------------------------------------------------------
 
-inline bool Thread::start()
+inline Thread::~Thread()
 {
-    return pthread_create(&thread, 0, &threadFn, this)>=0;
 }
 
Index: src/xplcommon/win32/Thread.cc
===================================================================
--- src/xplcommon/win32/Thread.cc	(revision 3)
+++ src/xplcommon/win32/Thread.cc	(revision 35)
@@ -40,5 +40,10 @@
 DWORD Thread::threadFn(LPVOID arg)
 {
-    reinterpret_cast<Thread*>(arg)->run();
+    Thread* thread = reinterpret_cast<Thread*>(arg);
+
+    thread->run();
+
+    if (thread->detached) delete thread;
+
     return 0;
 }
Index: src/xplcommon/win32/Thread.h
===================================================================
--- src/xplcommon/win32/Thread.h	(revision 20)
+++ src/xplcommon/win32/Thread.h	(revision 35)
@@ -58,4 +58,9 @@
 
     /**
+     * Indicate if the thread is detached.
+     */
+    bool detached;
+
+    /**
      * The thread handle.
      */
@@ -63,4 +68,9 @@
 
 public:
+    /**
+     * Construct the thread object.
+     */
+    Thread(bool detached = false);
+
     /**
      * Virtual destructor.
@@ -84,4 +94,6 @@
      */
     void join();
+
+    void release();
 };
 
@@ -97,4 +109,12 @@
 //------------------------------------------------------------------------------
 
+inline Thread::Thread(bool detached) :
+    detached(detached),
+    handle(0)
+{
+}
+
+//------------------------------------------------------------------------------
+
 inline Thread::~Thread()
 {
@@ -106,5 +126,10 @@
 {
     handle = CreateThread(0, 0, &threadFn, this, 0, 0);
-    return handle!=0;
+    bool isOK = handle!=0;
+    if (detached && handle!=0) {
+        CloseHandle(handle);
+        handle = 0;
+    }
+    return isOK;
 }
 
@@ -113,5 +138,8 @@
 inline void Thread::join()
 {
-    WaitForSingleObject(handle, INFINITE);
+    if (handle!=0) {
+        WaitForSingleObject(handle, INFINITE);
+        CloseHandle(handle);
+    }
 }
 
Index: test/Makefile.am
===================================================================
--- test/Makefile.am	(revision 34)
+++ test/Makefile.am	(revision 35)
@@ -1,7 +1,16 @@
 INCLUDES=-I$(top_srcdir)/src
 
-noinst_PROGRAMS=testevent testlocsock testblkstream testmutex testcondvar
+noinst_PROGRAMS=testthread testevent testlocsock testblkstream testmutex testcondvar
 if TARGET_API_POSIX
 noinst_PROGRAMS+=testrandom
+endif
+
+testthread_SOURCES=testthread.cc
+testthread_LDADD=../src/xplcommon/libxplcommon.la
+if TARGET_API_POSIX
+testthread_LDADD+=-lpthread
+endif
+if TARGET_API_WIN32
+testthread_LDFLAGS=-static-libgcc -static-libstdc++
 endif
 
Index: test/testblkstream.cc
===================================================================
--- test/testblkstream.cc	(revision 31)
+++ test/testblkstream.cc	(revision 35)
@@ -314,4 +314,5 @@
     clientThread.start();
 
+
     Thread::sleep(60000);
     //Thread::sleep(1000);
Index: test/testthread.cc
===================================================================
--- test/testthread.cc	(revision 35)
+++ test/testthread.cc	(revision 35)
@@ -0,0 +1,126 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+//------------------------------------------------------------------------------
+
+#include <xplcommon/Thread.h>
+#include <xplcommon/Waiter.h>
+#include <xplcommon/LocalServerSocket.h>
+#include <xplcommon/LocalAcceptor.h>
+#include <xplcommon/LocalSocket.h>
+#include <xplcommon/LocalClientSocket.h>
+#include <xplcommon/LocalConnector.h>
+#include <xplcommon/DataStream.h>
+#include <xplcommon/WaitableEvent.h>
+#include <xplcommon/PseudoRandom.h>
+
+#include <cstdlib>
+#include <cstdio>
+#include <cassert>
+
+#include <signal.h>
+
+#include <sys/time.h>
+
+//------------------------------------------------------------------------------
+
+using xplcommon::Thread;
+using xplcommon::Waiter;
+using xplcommon::LocalServerSocket;
+using xplcommon::LocalAcceptor;
+using xplcommon::LocalSocket;
+using xplcommon::LocalClientSocket;
+using xplcommon::LocalConnector;
+using xplcommon::BufferedStream;
+using xplcommon::DataStream;
+using xplcommon::PseudoRandom;
+
+using std::min;
+
+//------------------------------------------------------------------------------
+
+class TestThread : public Thread
+{
+private:
+    unsigned long id;
+
+public:
+    TestThread(unsigned long id);
+
+    virtual void run();
+};
+
+//------------------------------------------------------------------------------
+
+inline TestThread::TestThread(unsigned long id) :
+    Thread(true),
+    id(id)
+{
+}
+
+//------------------------------------------------------------------------------
+
+void TestThread::run()
+{
+    printf("TestThread: id=%lu\n", id);
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+int main()
+{
+    static const size_t numThreads = 1000;
+
+    TestThread** threads = new TestThread*[numThreads];
+
+    unsigned long id = 1;
+    while(true) {
+        for(size_t i = 0; i<numThreads; ++i) {
+            threads[i] = new TestThread(id++);
+            threads[i]->start();
+        }
+
+        Thread::sleep(2000);
+
+        // for(size_t i = 0; i<numThreads; ++i) {
+        //     delete threads[i];
+        // }
+    }
+
+    return 0;
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
