diff --git a/thread.c b/thread.c
index 93eb8c0d..5f76ca76 100644
--- a/thread.c
+++ b/thread.c
@@ -249,7 +249,11 @@ cThread::cThread(const char *Description, bool LowPriority)
 cThread::~cThread()
 {
   Cancel(); // just in case the derived class didn't call it
+  if (childTid)
+    pthread_join(childTid, NULL);
+  mutex.Lock();
   free(description);
+  mutex.Unlock();
 }
 
 void cThread::SetPriority(int Priority)
@@ -266,6 +270,7 @@ void cThread::SetIOPriority(int Priority)
 
 void cThread::SetDescription(const char *Description, ...)
 {
+  mutex.Lock();
   free(description);
   description = NULL;
   if (Description) {
@@ -274,6 +279,7 @@ void cThread::SetDescription(const char *Description, ...)
      description = strdup(cString::vsprintf(Description, ap));
      va_end(ap);
      }
+  mutex.Unlock();
 }
 
 void *cThread::StartThread(cThread *Thread)
@@ -291,8 +297,10 @@ void *cThread::StartThread(cThread *Thread)
      Thread->SetIOPriority(7);
      }
   Thread->Action();
+  Thread->mutex.Lock();
   if (Thread->description)
      dsyslog("%s thread ended (pid=%d, tid=%d)", Thread->description, getpid(), Thread->childThreadId);
+  Thread->mutex.Unlock();
   Thread->running = false;
   Thread->active = false;
   return NULL;
@@ -314,7 +322,6 @@ bool cThread::Start(void)
      if (!active) {
         active = running = true;
         if (pthread_create(&childTid, NULL, (void *(*) (void *))&StartThread, (void *)this) == 0) {
-           pthread_detach(childTid); // auto-reap
            }
         else {
            LOG_ERROR;
@@ -364,6 +371,7 @@ void cThread::Cancel(int WaitSeconds)
         esyslog("ERROR: %s thread %d won't end (waited %d seconds) - canceling it...", description ? description : "", childThreadId, WaitSeconds);
         }
      pthread_cancel(childTid);
+     pthread_join(childTid, NULL);
      childTid = 0;
      active = false;
      }
