X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fthread.C;h=dff53e61ec4e5eb656a09236f4486ef680ee7484;hp=c3d068e0b3c867bfadd06572433bfa27b63c2d49;hb=c279e21fc2394a7908bbd1ba8c79b116fe9fb14a;hpb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd diff --git a/cinelerra-5.1/guicast/thread.C b/cinelerra-5.1/guicast/thread.C index c3d068e0..dff53e61 100644 --- a/cinelerra-5.1/guicast/thread.C +++ b/cinelerra-5.1/guicast/thread.C @@ -2,107 +2,33 @@ /* * CINELERRA * Copyright (C) 2008 Adam Williams - * + * * 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 #include #include #include #include #include -#include "thread.h" - -// track unjoined threads at termination -#ifndef NO_GUICAST -#include "arraylist.h" -#include "mutex.h" #include +#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 { -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; }