refresh frame fix, dblclk proxy viewer fix, vicon refresh fix for awdw resize, fix...
[goodguy/history.git] / cinelerra-5.1 / guicast / thread.C
index c3d068e0b3c867bfadd06572433bfa27b63c2d49..dff53e61ec4e5eb656a09236f4486ef680ee7484 100644 (file)
 /*
  * CINELERRA
  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
+ *
  */
 
-#ifndef NO_GUICAST
 #include "bcsignals.h"
-#endif
 #include <sys/wait.h>
 #include <sched.h>
 #include <signal.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
-#include "thread.h"
-
-// track unjoined threads at termination
-#ifndef NO_GUICAST
-#include "arraylist.h"
-#include "mutex.h"
 #include <typeinfo>
+#include "thread.h"
 
-class MLocker {
-       static Mutex the_lock;
-public:
-       MLocker() { the_lock.lock(); }
-       ~MLocker() { the_lock.unlock(); }
-};
-Mutex MLocker::the_lock;
-
-class the_dbg {
-public:
-       pthread_t tid;  const char *name;
-       the_dbg(pthread_t t, const char *nm) { tid = t; name = nm; }
-       ~the_dbg() {}
-};
-
-
-static class the_list : public ArrayList<the_dbg*> {
-public:
-       static void dump_threads(FILE *fp);
-        the_list() {}
-       ~the_list() {
-               MLocker mlkr;
-               remove_all_objects();
-       }
-} thread_list;
-
-static void dbg_add(pthread_t tid, const char *nm)
-{
-       MLocker mlkr;
-       int i = thread_list.size();
-       while( --i >= 0 && thread_list[i]->tid != tid );
-       if( i >= 0 ) {
-               printf("dbg_add, dup %016lx %s %s\n",
-                       (unsigned long)tid, nm, thread_list[i]->name);
-               return;
-       }
-       thread_list.append(new the_dbg(tid, nm));
-}
-
-static void dbg_del(pthread_t tid)
-{
-       MLocker mlkr;
-       int i = thread_list.size();
-       while( --i >= 0 && thread_list[i]->tid != tid );
-       if( i < 0 ) {
-               printf("dbg_del, mis %016lx\n",(unsigned long)tid);
-               return;
-       }
-       thread_list.remove_object_number(i);
-}
-
-static class the_chkr {
-public:
-       the_chkr() {}
-       ~the_chkr() {
-               int i = thread_list.size();
-               if( !i ) return;
-               printf("unjoined tids %d\n", i);
-               while( --i >= 0 ) printf("  %016lx %s\n",
-                       (unsigned long)thread_list[i]->tid,
-                       thread_list[i]->name);
-       }
-} the_chk;
-#else
-#define dbg_add(t, nm) do {} while(0)
-#define dbg_del(t) do {} while(0)
-#endif
 
 Thread::Thread(int synchronous, int realtime, int autodelete)
 {
@@ -139,8 +65,8 @@ void* Thread::entrypoint(void *parameters)
        thread->run();
        thread->finished = true;
        if( !thread->synchronous ) {
-               if( !thread->cancelled ) dbg_del(thread->tid);
                if( thread->autodelete ) delete thread;
+               else if( !thread->cancelled ) TheList::dbg_del(thread->tid);
                else thread->tid = ((pthread_t)-1);
        }
        return NULL;
@@ -180,9 +106,13 @@ void Thread::start()
                        perror("Thread::start pthread_attr_setinheritsched");
        }
 
+// autodelete may delete this immediately after create
+       int autodelete = this->autodelete;
+
        pthread_create(&tid, &attr, Thread::entrypoint, this);
 
-       dbg_add(tid, typeid(*this).name());
+       if( !autodelete )
+               TheList::dbg_add(tid, owner, typeid(*this).name());
 }
 
 int Thread::cancel()
@@ -191,7 +121,7 @@ int Thread::cancel()
                LOCK_LOCKS("Thread::cancel");
                pthread_cancel(tid);
                cancelled = true;
-               if( !synchronous ) dbg_del(tid);
+               if( !synchronous ) TheList::dbg_del(tid);
                UNLOCK_LOCKS;
        }
        return 0;
@@ -201,11 +131,16 @@ int Thread::join()   // join this thread
 {
        if( !exists() ) return 0;
        if( synchronous ) {
-// NOTE: this does not do anything if the thread is not synchronous
+// NOTE: this fails if the thread is not synchronous or
+//  or another thread is already waiting to join.
                int ret = pthread_join(tid, 0);
-               if( ret ) strerror(ret);
+               if( ret ) {
+                       fflush(stdout);
+                       fprintf(stderr, "Thread %p: %s\n", (void*)tid, strerror(ret));
+                       fflush(stderr);
+               }
                CLEAR_LOCKS_TID(tid);
-               dbg_del(tid);
+               TheList::dbg_del(tid);
                tid = ((pthread_t)-1);
 // Don't execute anything after this.
                if( autodelete ) delete this;
@@ -215,7 +150,7 @@ int Thread::join()   // join this thread
                while( running() && !cancelled ) {
                        int ret = pthread_kill(tid, 0);
                        if( ret ) break;
-                       usleep(200000);
+                       usleep(10000);
                }
                tid = ((pthread_t)-1);
        }
@@ -308,16 +243,6 @@ int Thread::get_realtime()
 
 unsigned long Thread::get_tid()
 {
-       return tid;
-}
-
-void Thread::dump_threads(FILE *fp)
-{
-       int i = thread_list.size();
-       while( --i >= 0 ) {
-               fprintf(fp, "thread %016lx, %s\n",
-                       (unsigned long)thread_list[i]->tid,
-                       thread_list[i]->name);
-       }
+       return (unsigned long)tid;
 }