X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fpthread_utils.cc;h=d9e5ca40785f6c2aba4e76ad5876b68da8121338;hb=8fcf7e6a0785556602df0502a4c02707a432f0b6;hp=ca636034468d68021cb6b70d96d0c82be120391f;hpb=c83389b8ec5fef9553a401e6123b7e55702af9e2;p=ardour.git diff --git a/libs/pbd/pthread_utils.cc b/libs/pbd/pthread_utils.cc index ca63603446..d9e5ca4078 100644 --- a/libs/pbd/pthread_utils.cc +++ b/libs/pbd/pthread_utils.cc @@ -18,9 +18,10 @@ $Id$ */ -#include +#include #include #include +#include #include #include "pbd/pthread_utils.h" @@ -30,9 +31,10 @@ using namespace std; -typedef std::map ThreadMap; +typedef std::set ThreadMap; static ThreadMap all_threads; static pthread_mutex_t thread_map_lock = PTHREAD_MUTEX_INITIALIZER; +static Glib::StaticPrivate thread_name; namespace PBD { PBD::Signal4 ThreadCreatedWithRequestSize; @@ -55,23 +57,45 @@ PBD::notify_gui_about_thread_creation (std::string target_gui, pthread_t thread, ThreadCreatedWithRequestSize (target_gui, thread, str, 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) {} +}; + +static void* +fake_thread_start (void* arg) +{ + ThreadStartWithName* ts = (ThreadStartWithName*) arg; + void* (*thread_work)(void*) = ts->thread_work; + void* thread_arg = ts->arg; + + pthread_set_name (ts->name.c_str()); + + delete ts; + /* name will be deleted by the default handler for GStaticPrivate, when the thread exits */ + + return thread_work (thread_arg); +} + int pthread_create_and_store (string name, pthread_t *thread, void * (*start_routine)(void *), void * arg) { pthread_attr_t default_attr; int ret; - + // set default stack size to sensible default for memlocking pthread_attr_init(&default_attr); pthread_attr_setstacksize(&default_attr, 500000); - if ((ret = thread_creator (thread, &default_attr, start_routine, arg)) == 0) { - std::pair newpair; - newpair.first = name; - newpair.second = *thread; + ThreadStartWithName* ts = new ThreadStartWithName (start_routine, arg, name); + if ((ret = thread_creator (thread, &default_attr, fake_thread_start, ts)) == 0) { pthread_mutex_lock (&thread_map_lock); - all_threads.insert (newpair); + all_threads.insert (*thread); pthread_mutex_unlock (&thread_map_lock); } @@ -80,21 +104,22 @@ pthread_create_and_store (string name, pthread_t *thread, void * (*start_routin return ret; } -string +void +pthread_set_name (const char *str) +{ + /* copy string and delete it when exiting */ + + thread_name.set (strdup (str), free); +} + +const char * pthread_name () { - pthread_t self = pthread_self(); - string str; + const char* str = thread_name.get (); - pthread_mutex_lock (&thread_map_lock); - for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { - if (i->second == self) { - str = i->first; - pthread_mutex_unlock (&thread_map_lock); - return str; - } - } - pthread_mutex_unlock (&thread_map_lock); + if (str) { + return str; + } return "unknown"; } @@ -103,8 +128,8 @@ pthread_kill_all (int signum) { pthread_mutex_lock (&thread_map_lock); for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { - if (i->second != pthread_self()) { - pthread_kill (i->second, signum); + if ((*i) != pthread_self()) { + pthread_kill ((*i), signum); } } all_threads.clear(); @@ -116,8 +141,8 @@ pthread_cancel_all () { pthread_mutex_lock (&thread_map_lock); for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { - if (i->second != pthread_self()) { - pthread_cancel (i->second); + if ((*i) != pthread_self()) { + pthread_cancel ((*i)); } } all_threads.clear(); @@ -129,7 +154,7 @@ 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 (i->second == thread) { + if ((*i) == thread) { all_threads.erase (i); break; } @@ -146,7 +171,7 @@ pthread_exit_pbd (void* status) pthread_mutex_lock (&thread_map_lock); for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) { - if (i->second == thread) { + if ((*i) == thread) { all_threads.erase (i); break; }