X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fpthread_utils.cc;h=5daa60ac424aec37fd6252bd0d2c490f59af04e8;hb=78b82b7ff2e28d53faae176776491404115ce02c;hp=6bc02e088319d031cbc2a1338bb3ed4ab939db88;hpb=117118e5f07da862a8a7901c60e880507c3be2d4;p=ardour.git diff --git a/libs/pbd/pthread_utils.cc b/libs/pbd/pthread_utils.cc index 6bc02e0883..5daa60ac42 100644 --- a/libs/pbd/pthread_utils.cc +++ b/libs/pbd/pthread_utils.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2002 Paul Davis + Copyright (C) 2002 Paul Davis 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 @@ -28,15 +28,23 @@ #include #endif +#ifdef COMPILER_MSVC +DECLARE_DEFAULT_COMPARISONS(pthread_t) // Needed for 'DECLARE_DEFAULT_COMPARISONS'. Objects in an STL container can be + // searched and sorted. Thus, when instantiating the container, MSVC complains + // if the type of object being contained has no appropriate comparison operators + // defined (specifically, if operators '<' and '==' are undefined). This seems + // to be the case with ptw32 'pthread_t' which is a simple struct. +#endif + using namespace std; -typedef std::set ThreadMap; +typedef std::list ThreadMap; static ThreadMap all_threads; static pthread_mutex_t thread_map_lock = PTHREAD_MUTEX_INITIALIZER; static Glib::Threads::Private thread_name (free); namespace PBD { - PBD::Signal4 ThreadCreatedWithRequestSize; + PBD::Signal3 ThreadCreatedWithRequestSize; } using namespace PBD; @@ -50,17 +58,25 @@ static int thread_creator (pthread_t* thread_id, const pthread_attr_t* attr, voi #endif } + void -PBD::notify_gui_about_thread_creation (std::string target_gui, pthread_t thread, std::string str, int request_count) +PBD::notify_event_loops_about_thread_creation (pthread_t thread, const std::string& emitting_thread_name, int request_count) { - ThreadCreatedWithRequestSize (target_gui, thread, str, request_count); + /* notify threads that may exist in the future (they may also exist + * already, in which case they will catch the + * ThreadCreatedWithRequestSize signal) + */ + EventLoop::pre_register (emitting_thread_name, request_count); + + /* notify all existing threads */ + ThreadCreatedWithRequestSize (thread, emitting_thread_name, request_count); } struct ThreadStartWithName { void* (*thread_work)(void*); void* arg; std::string name; - + ThreadStartWithName (void* (*f)(void*), void* a, const std::string& s) : thread_work (f), arg (a), name (s) {} }; @@ -72,15 +88,37 @@ fake_thread_start (void* arg) void* (*thread_work)(void*) = ts->thread_work; void* thread_arg = ts->arg; + /* name will be deleted by the default handler for GStaticPrivate, when the thread exits */ + pthread_set_name (ts->name.c_str()); + /* we don't need this object anymore */ + delete ts; - /* name will be deleted by the default handler for GStaticPrivate, when the thread exits */ - return thread_work (thread_arg); + /* actually run the thread's work function */ + + void* ret = thread_work (thread_arg); + + /* cleanup */ + + pthread_mutex_lock (&thread_map_lock); + + for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { + if (pthread_equal ((*i), pthread_self())) { + all_threads.erase (i); + break; + } + } + + pthread_mutex_unlock (&thread_map_lock); + + /* done */ + + return ret; } -int +int pthread_create_and_store (string name, pthread_t *thread, void * (*start_routine)(void *), void * arg) { pthread_attr_t default_attr; @@ -94,7 +132,7 @@ pthread_create_and_store (string name, pthread_t *thread, void * (*start_routin if ((ret = thread_creator (thread, &default_attr, fake_thread_start, ts)) == 0) { pthread_mutex_lock (&thread_map_lock); - all_threads.insert (*thread); + all_threads.push_back (*thread); pthread_mutex_unlock (&thread_map_lock); } @@ -107,8 +145,8 @@ void pthread_set_name (const char *str) { /* copy string and delete it when exiting */ - - thread_name.set (strdup (str)); + + thread_name.set (strdup (str)); // leaks } const char * @@ -118,13 +156,13 @@ pthread_name () if (str) { return str; - } + } return "unknown"; } void -pthread_kill_all (int signum) -{ +pthread_kill_all (int signum) +{ pthread_mutex_lock (&thread_map_lock); for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { if (!pthread_equal ((*i), pthread_self())) { @@ -136,21 +174,28 @@ pthread_kill_all (int signum) } void -pthread_cancel_all () -{ +pthread_cancel_all () +{ pthread_mutex_lock (&thread_map_lock); - for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { + + for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ) { + + ThreadMap::iterator nxt = i; + ++nxt; + if (!pthread_equal ((*i), pthread_self())) { pthread_cancel ((*i)); } + + i = nxt; } all_threads.clear(); pthread_mutex_unlock (&thread_map_lock); } void -pthread_cancel_one (pthread_t thread) -{ +pthread_cancel_one (pthread_t thread) +{ pthread_mutex_lock (&thread_map_lock); for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { if (pthread_equal ((*i), thread)) { @@ -162,19 +207,3 @@ pthread_cancel_one (pthread_t thread) pthread_cancel (thread); pthread_mutex_unlock (&thread_map_lock); } - -void -pthread_exit_pbd (void* status) -{ - pthread_t thread = pthread_self(); - - pthread_mutex_lock (&thread_map_lock); - for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { - if (pthread_equal ((*i), thread)) { - all_threads.erase (i); - break; - } - } - pthread_mutex_unlock (&thread_map_lock); - pthread_exit (status); -}