From b2c341f935bd54eb1b7f80a297e72bf0e6c6dc83 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Aug 2006 19:51:14 +0000 Subject: add a threading primitive API git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1344 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 146 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 src/pulsecore/thread-posix.c (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c new file mode 100644 index 00000000..15ade290 --- /dev/null +++ b/src/pulsecore/thread-posix.c @@ -0,0 +1,146 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio 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 Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "thread.h" + +#define ASSERT_SUCCESS(x) do { \ + int _r = (x); \ + assert(_r == 0); \ +} while(0) + +struct pa_thread { + pthread_t id; + pa_thread_func_t thread_func; + void *userdata; + AO_t running; +}; + +struct pa_tls { + pthread_key_t key; +}; + +static pa_tls *thread_tls; +static pthread_once_t thread_tls_once = PTHREAD_ONCE_INIT; + +static void thread_tls_once_func(void) { + thread_tls = pa_tls_new(NULL); + assert(thread_tls); +} + +static void* internal_thread_func(void *userdata) { + pa_thread *t = userdata; + assert(t); + + t->id = pthread_self(); + + ASSERT_SUCCESS(pthread_once(&thread_tls_once, thread_tls_once_func)); + pa_tls_set(thread_tls, t); + + AO_store_release_write(&t->running, 1); + t->thread_func(t->userdata); + AO_store_release_write(&t->running, 0); + + return NULL; +} + +pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) { + pa_thread *t; + + t = pa_xnew(pa_thread, 1); + t->thread_func = thread_func; + t->userdata = userdata; + + if (pthread_create(&t->id, NULL, internal_thread_func, t) < 0) { + pa_xfree(t); + return NULL; + } + + return t; +} + +int pa_thread_is_running(pa_thread *t) { + assert(t); + + return !!AO_load_acquire_read(&t->running); +} + +void pa_thread_free(pa_thread *t) { + assert(t); + + pa_thread_join(t); + pa_xfree(t); +} + +int pa_thread_join(pa_thread *t) { + assert(t); + + return pthread_join(t->id, NULL); +} + +pa_thread* pa_thread_self(void) { + ASSERT_SUCCESS(pthread_once(&thread_tls_once, thread_tls_once_func)); + return pa_tls_get(thread_tls); +} + +pa_tls* pa_tls_new(pa_free_cb_t free_cb) { + pa_tls *t; + + t = pa_xnew(pa_tls, 1); + + if (pthread_key_create(&t->key, free_cb) < 0) { + pa_xfree(t); + return NULL; + } + + return t; +} + +void pa_tls_free(pa_tls *t) { + assert(t); + + ASSERT_SUCCESS(pthread_key_delete(t->key)); + pa_xfree(t); +} + +void *pa_tls_get(pa_tls *t) { + assert(t); + + return pthread_getspecific(t->key); +} + +void *pa_tls_set(pa_tls *t, void *userdata) { + void *r; + + r = pthread_getspecific(t->key); + ASSERT_SUCCESS(pthread_setspecific(t->key, userdata)); + return r; +} + -- cgit From ad0535beef4cd0d4e96fa194d54796a0945ed3c6 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 30 Aug 2006 17:01:10 +0000 Subject: Add AO_REQUIRE_CAS as we do. git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1348 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 15ade290..54f21b75 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -25,6 +25,8 @@ #include #include + +#define AO_REQUIRE_CAS #include #include -- cgit From 2f6cc4f8fa8d806ef6120887cd3aed62b1b072c0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Aug 2006 17:12:35 +0000 Subject: fix handling of "running" variable git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1349 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 54f21b75..b634a6f6 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -66,9 +66,9 @@ static void* internal_thread_func(void *userdata) { ASSERT_SUCCESS(pthread_once(&thread_tls_once, thread_tls_once_func)); pa_tls_set(thread_tls, t); - AO_store_release_write(&t->running, 1); + AO_fetch_and_add1_full(&t->running); t->thread_func(t->userdata); - AO_store_release_write(&t->running, 0); + AO_fetch_and_add_full(&t->running, (AO_t) -2); return NULL; } @@ -79,19 +79,24 @@ pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) { t = pa_xnew(pa_thread, 1); t->thread_func = thread_func; t->userdata = userdata; + AO_store_full(&t->running, 0); if (pthread_create(&t->id, NULL, internal_thread_func, t) < 0) { pa_xfree(t); return NULL; } + AO_fetch_and_add1_full(&t->running); + return t; } int pa_thread_is_running(pa_thread *t) { + AO_t r; assert(t); - return !!AO_load_acquire_read(&t->running); + r = AO_load_full(&t->running); + return r == 1 || r == 2; } void pa_thread_free(pa_thread *t) { -- cgit From aee4a3738eaa5026a5ade1e865f67860c9bc004f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 31 Aug 2006 15:20:43 +0000 Subject: define AO_REQUIRE_CAS in the Makefile instead of each source file, effectively reversing r1348 git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1351 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index b634a6f6..6ca46d70 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -26,7 +26,6 @@ #include #include -#define AO_REQUIRE_CAS #include #include -- cgit From 6e9706bcbcc0c5743d21ed48bd6e6485e4ee5203 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 31 Aug 2006 16:13:07 +0000 Subject: Also wrap yield functionality so that it can be platform independent. git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1353 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 6ca46d70..4c12ec93 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -25,6 +25,7 @@ #include #include +#include #include @@ -116,6 +117,14 @@ pa_thread* pa_thread_self(void) { return pa_tls_get(thread_tls); } +void pa_thread_yield(void) { +#ifdef HAVE_PTHREAD_YIELD + pthread_yield(); +#else + sched_yield(); +#endif +} + pa_tls* pa_tls_new(pa_free_cb_t free_cb) { pa_tls *t; -- cgit From f84c65ed86ae59aae6e9a48e62aca31eaa30e2e3 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 1 Sep 2006 18:39:55 +0000 Subject: Add pthread_once() equivalent support. git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1357 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 4c12ec93..bc71ea47 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -30,6 +30,7 @@ #include #include +#include #include "thread.h" @@ -52,6 +53,9 @@ struct pa_tls { static pa_tls *thread_tls; static pthread_once_t thread_tls_once = PTHREAD_ONCE_INIT; +static pa_mutex *once_mutex; +static pthread_once_t thread_once_once = PTHREAD_ONCE_INIT; + static void thread_tls_once_func(void) { thread_tls = pa_tls_new(NULL); assert(thread_tls); @@ -125,6 +129,27 @@ void pa_thread_yield(void) { #endif } +static void thread_once_once_func(void) { + once_mutex = pa_mutex_new(); + assert(once_mutex); +} + +void pa_thread_once(pa_thread_once_t *control, pa_thread_once_func_t once_func) { + assert(control); + assert(once_func); + + ASSERT_SUCCESS(pthread_once(&thread_once_once, thread_once_once_func)); + + pa_mutex_lock(once_mutex); + + if (*control == PA_THREAD_ONCE_INIT) { + *control = ~PA_THREAD_ONCE_INIT; + pa_mutex_unlock(once_mutex); + once_func(); + } else + pa_mutex_unlock(once_mutex); +} + pa_tls* pa_tls_new(pa_free_cb_t free_cb) { pa_tls *t; -- cgit From 647ef180c3dac933963fdfeca53772bd3be894ae Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 1 Sep 2006 19:06:44 +0000 Subject: Fix call to pa_mutex_new(). git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1358 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index bc71ea47..2e8d6b68 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -130,7 +130,7 @@ void pa_thread_yield(void) { } static void thread_once_once_func(void) { - once_mutex = pa_mutex_new(); + once_mutex = pa_mutex_new(0); assert(once_mutex); } -- cgit From 8e7c2a3b0c2fd67802222b3f216bc67bb2c1fe70 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Sep 2006 21:28:34 +0000 Subject: make pa_thread_self() return a sensible pointer on foreign threads git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1368 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 2e8d6b68..43ad2d52 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -117,15 +117,32 @@ int pa_thread_join(pa_thread *t) { } pa_thread* pa_thread_self(void) { + pa_thread *t; + ASSERT_SUCCESS(pthread_once(&thread_tls_once, thread_tls_once_func)); - return pa_tls_get(thread_tls); + + if ((t = pa_tls_get(thread_tls))) + return t; + + /* This is a foreign thread, let's create a pthread structure to + * make sure that we can always return a sensible pointer */ + + t = pa_xnew(pa_thread, 1); + t->id = pthread_self(); + t->thread_func = NULL; + t->userdata = NULL; + AO_store_full(&t->running, 1); + + pa_tls_set(thread_tls, t); + + return t; } void pa_thread_yield(void) { #ifdef HAVE_PTHREAD_YIELD pthread_yield(); #else - sched_yield(); + ASSERT_SUCCESS(sched_yield()); #endif } -- cgit From 3be920d9aec656e7e34672558e85ba025a4059d0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Sep 2006 22:04:33 +0000 Subject: fix pa_thread_is_running() for foreign threads; fix a memory leak for foreign threads git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1370 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 43ad2d52..1b9a94a3 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -56,8 +57,18 @@ static pthread_once_t thread_tls_once = PTHREAD_ONCE_INIT; static pa_mutex *once_mutex; static pthread_once_t thread_once_once = PTHREAD_ONCE_INIT; +static void tls_free_cb(void *p) { + pa_thread *t = p; + + assert(t); + + if (!t->thread_func) + /* This is a foreign thread, we need to free the struct */ + pa_xfree(t); +} + static void thread_tls_once_func(void) { - thread_tls = pa_tls_new(NULL); + thread_tls = pa_tls_new(tls_free_cb); assert(thread_tls); } @@ -80,6 +91,8 @@ static void* internal_thread_func(void *userdata) { pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) { pa_thread *t; + assert(thread_func); + t = pa_xnew(pa_thread, 1); t->thread_func = thread_func; t->userdata = userdata; @@ -99,6 +112,17 @@ int pa_thread_is_running(pa_thread *t) { AO_t r; assert(t); + if (!t->thread_func) { + /* Mhmm, this is a foreign thread, t->running is not + * necessarily valid. We misuse pthread_getschedparam() to + * check if the thread is valid. This might not be portable. */ + + int policy; + struct sched_param param; + + return pthread_getschedparam(t->id, &policy, ¶m) >= 0 || errno != ESRCH; + } + r = AO_load_full(&t->running); return r == 1 || r == 2; } -- cgit From 6bbfb43f2ac597c2d1ba95b0c4b7c9619dcb9a35 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Sep 2006 22:15:15 +0000 Subject: add accessor functions for the userdata attached to a pa_thread object git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1371 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 1b9a94a3..a2cb9b56 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -162,6 +162,18 @@ pa_thread* pa_thread_self(void) { return t; } +void* pa_thread_get_data(pa_thread *t) { + assert(t); + + return t->userdata; +} + +void pa_thread_set_data(pa_thread *t, void *userdata) { + assert(t); + + t->userdata = userdata; +} + void pa_thread_yield(void) { #ifdef HAVE_PTHREAD_YIELD pthread_yield(); -- cgit From 6d532029eaac08a3b60a28752f23f0586f895168 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 9 Sep 2006 22:59:17 +0000 Subject: update for newer APIs: replace direct usage of libatomic_ops by usage of our own atomic.h; remove pa_once implementation; always use our pa_once implementation instead of the POSIX version git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1386 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 51 +++++++++++--------------------------------- 1 file changed, 13 insertions(+), 38 deletions(-) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index a2cb9b56..d69790a5 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -28,10 +28,10 @@ #include #include -#include - #include #include +#include +#include #include "thread.h" @@ -44,7 +44,7 @@ struct pa_thread { pthread_t id; pa_thread_func_t thread_func; void *userdata; - AO_t running; + pa_atomic_int_t running; }; struct pa_tls { @@ -52,10 +52,7 @@ struct pa_tls { }; static pa_tls *thread_tls; -static pthread_once_t thread_tls_once = PTHREAD_ONCE_INIT; - -static pa_mutex *once_mutex; -static pthread_once_t thread_once_once = PTHREAD_ONCE_INIT; +static pa_once_t thread_tls_once = PA_ONCE_INIT; static void tls_free_cb(void *p) { pa_thread *t = p; @@ -78,12 +75,13 @@ static void* internal_thread_func(void *userdata) { t->id = pthread_self(); - ASSERT_SUCCESS(pthread_once(&thread_tls_once, thread_tls_once_func)); + pa_once(&thread_tls_once, thread_tls_once_func); + pa_tls_set(thread_tls, t); - AO_fetch_and_add1_full(&t->running); + pa_atomic_inc(&t->running); t->thread_func(t->userdata); - AO_fetch_and_add_full(&t->running, (AO_t) -2); + pa_atomic_add(&t->running, -2); return NULL; } @@ -96,20 +94,19 @@ pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) { t = pa_xnew(pa_thread, 1); t->thread_func = thread_func; t->userdata = userdata; - AO_store_full(&t->running, 0); + pa_atomic_store(&t->running, 0); if (pthread_create(&t->id, NULL, internal_thread_func, t) < 0) { pa_xfree(t); return NULL; } - AO_fetch_and_add1_full(&t->running); + pa_atomic_inc(&t->running); return t; } int pa_thread_is_running(pa_thread *t) { - AO_t r; assert(t); if (!t->thread_func) { @@ -123,8 +120,7 @@ int pa_thread_is_running(pa_thread *t) { return pthread_getschedparam(t->id, &policy, ¶m) >= 0 || errno != ESRCH; } - r = AO_load_full(&t->running); - return r == 1 || r == 2; + return pa_atomic_load(&t->running) > 0; } void pa_thread_free(pa_thread *t) { @@ -143,7 +139,7 @@ int pa_thread_join(pa_thread *t) { pa_thread* pa_thread_self(void) { pa_thread *t; - ASSERT_SUCCESS(pthread_once(&thread_tls_once, thread_tls_once_func)); + pa_once(&thread_tls_once, thread_tls_once_func); if ((t = pa_tls_get(thread_tls))) return t; @@ -155,7 +151,7 @@ pa_thread* pa_thread_self(void) { t->id = pthread_self(); t->thread_func = NULL; t->userdata = NULL; - AO_store_full(&t->running, 1); + pa_atomic_store(&t->running, 2); pa_tls_set(thread_tls, t); @@ -182,27 +178,6 @@ void pa_thread_yield(void) { #endif } -static void thread_once_once_func(void) { - once_mutex = pa_mutex_new(0); - assert(once_mutex); -} - -void pa_thread_once(pa_thread_once_t *control, pa_thread_once_func_t once_func) { - assert(control); - assert(once_func); - - ASSERT_SUCCESS(pthread_once(&thread_once_once, thread_once_once_func)); - - pa_mutex_lock(once_mutex); - - if (*control == PA_THREAD_ONCE_INIT) { - *control = ~PA_THREAD_ONCE_INIT; - pa_mutex_unlock(once_mutex); - once_func(); - } else - pa_mutex_unlock(once_mutex); -} - pa_tls* pa_tls_new(pa_free_cb_t free_cb) { pa_tls *t; -- cgit From 521daf6f0ac4fa6a2fbfb5d523c0c743342dca2b Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 4 Jan 2007 13:43:45 +0000 Subject: Huge trailing whitespace cleanup. Let's keep the tree pure from here on, mmmkay? git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1418 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index d69790a5..dcd45ea7 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -2,17 +2,17 @@ /*** This file is part of PulseAudio. - + PulseAudio is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + PulseAudio 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 Lesser General Public License along with PulseAudio; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 @@ -58,8 +58,8 @@ static void tls_free_cb(void *p) { pa_thread *t = p; assert(t); - - if (!t->thread_func) + + if (!t->thread_func) /* This is a foreign thread, we need to free the struct */ pa_xfree(t); } @@ -76,13 +76,13 @@ static void* internal_thread_func(void *userdata) { t->id = pthread_self(); pa_once(&thread_tls_once, thread_tls_once_func); - + pa_tls_set(thread_tls, t); - + pa_atomic_inc(&t->running); t->thread_func(t->userdata); pa_atomic_add(&t->running, -2); - + return NULL; } @@ -90,7 +90,7 @@ pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) { pa_thread *t; assert(thread_func); - + t = pa_xnew(pa_thread, 1); t->thread_func = thread_func; t->userdata = userdata; @@ -116,7 +116,7 @@ int pa_thread_is_running(pa_thread *t) { int policy; struct sched_param param; - + return pthread_getschedparam(t->id, &policy, ¶m) >= 0 || errno != ESRCH; } @@ -125,20 +125,20 @@ int pa_thread_is_running(pa_thread *t) { void pa_thread_free(pa_thread *t) { assert(t); - + pa_thread_join(t); pa_xfree(t); } int pa_thread_join(pa_thread *t) { assert(t); - + return pthread_join(t->id, NULL); } pa_thread* pa_thread_self(void) { pa_thread *t; - + pa_once(&thread_tls_once, thread_tls_once_func); if ((t = pa_tls_get(thread_tls))) @@ -146,7 +146,7 @@ pa_thread* pa_thread_self(void) { /* This is a foreign thread, let's create a pthread structure to * make sure that we can always return a sensible pointer */ - + t = pa_xnew(pa_thread, 1); t->id = pthread_self(); t->thread_func = NULL; @@ -154,7 +154,7 @@ pa_thread* pa_thread_self(void) { pa_atomic_store(&t->running, 2); pa_tls_set(thread_tls, t); - + return t; } @@ -187,7 +187,7 @@ pa_tls* pa_tls_new(pa_free_cb_t free_cb) { pa_xfree(t); return NULL; } - + return t; } @@ -200,13 +200,13 @@ void pa_tls_free(pa_tls *t) { void *pa_tls_get(pa_tls *t) { assert(t); - + return pthread_getspecific(t->key); } void *pa_tls_set(pa_tls *t, void *userdata) { void *r; - + r = pthread_getspecific(t->key); ASSERT_SUCCESS(pthread_setspecific(t->key, userdata)); return r; -- cgit From 06211b7c8fd329137ae9003818543912a87d9898 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 13 Feb 2007 15:35:19 +0000 Subject: Add copyright notices to all relevant files. (based on svn log) git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1426 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index dcd45ea7..7ff5e7c3 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -3,6 +3,9 @@ /*** This file is part of PulseAudio. + Copyright 2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + PulseAudio is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, -- cgit From 6a2dffd78af88ec3c3089c3a852af6d3a6b499bf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 27 May 2007 16:59:34 +0000 Subject: unfortunately we cannot detect if a foreign thread is still running. Thus sucks. But what can we do? U. Drepper thinks our use case is invalid. git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1458 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 7ff5e7c3..b3274426 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -111,17 +111,12 @@ pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) { int pa_thread_is_running(pa_thread *t) { assert(t); - - if (!t->thread_func) { - /* Mhmm, this is a foreign thread, t->running is not - * necessarily valid. We misuse pthread_getschedparam() to - * check if the thread is valid. This might not be portable. */ - - int policy; - struct sched_param param; - - return pthread_getschedparam(t->id, &policy, ¶m) >= 0 || errno != ESRCH; - } + + /* Unfortunately there is no way to tell whether a "foreign" + * thread is still running. See + * http://udrepper.livejournal.com/16844.html for more + * information */ + assert(t->thread_func); return pa_atomic_load(&t->running) > 0; } -- cgit From 1e12e0ee8dfdda1632b9c082aba6fc1956813a5b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 May 2007 17:24:48 +0000 Subject: Kill spaces on EOL git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1465 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index b3274426..4271fa42 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -111,7 +111,7 @@ pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) { int pa_thread_is_running(pa_thread *t) { assert(t); - + /* Unfortunately there is no way to tell whether a "foreign" * thread is still running. See * http://udrepper.livejournal.com/16844.html for more -- cgit From a67c21f093202f142438689d3f7cfbdf4ea82eea Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 28 Oct 2007 19:13:50 +0000 Subject: merge 'lennart' branch back into trunk. git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1971 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-posix.c | 59 +++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 37 deletions(-) (limited to 'src/pulsecore/thread-posix.c') diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 4271fa42..7f43f43e 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include #include @@ -35,56 +34,44 @@ #include #include #include +#include #include "thread.h" -#define ASSERT_SUCCESS(x) do { \ - int _r = (x); \ - assert(_r == 0); \ -} while(0) - struct pa_thread { pthread_t id; pa_thread_func_t thread_func; void *userdata; - pa_atomic_int_t running; + pa_atomic_t running; }; struct pa_tls { pthread_key_t key; }; -static pa_tls *thread_tls; -static pa_once_t thread_tls_once = PA_ONCE_INIT; - -static void tls_free_cb(void *p) { +static void thread_free_cb(void *p) { pa_thread *t = p; - assert(t); + pa_assert(t); if (!t->thread_func) /* This is a foreign thread, we need to free the struct */ pa_xfree(t); } -static void thread_tls_once_func(void) { - thread_tls = pa_tls_new(tls_free_cb); - assert(thread_tls); -} +PA_STATIC_TLS_DECLARE(current_thread, thread_free_cb); static void* internal_thread_func(void *userdata) { pa_thread *t = userdata; - assert(t); + pa_assert(t); t->id = pthread_self(); - pa_once(&thread_tls_once, thread_tls_once_func); - - pa_tls_set(thread_tls, t); + PA_STATIC_TLS_SET(current_thread, t); pa_atomic_inc(&t->running); t->thread_func(t->userdata); - pa_atomic_add(&t->running, -2); + pa_atomic_sub(&t->running, 2); return NULL; } @@ -92,7 +79,7 @@ static void* internal_thread_func(void *userdata) { pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) { pa_thread *t; - assert(thread_func); + pa_assert(thread_func); t = pa_xnew(pa_thread, 1); t->thread_func = thread_func; @@ -110,26 +97,26 @@ pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) { } int pa_thread_is_running(pa_thread *t) { - assert(t); + pa_assert(t); /* Unfortunately there is no way to tell whether a "foreign" * thread is still running. See * http://udrepper.livejournal.com/16844.html for more * information */ - assert(t->thread_func); + pa_assert(t->thread_func); return pa_atomic_load(&t->running) > 0; } void pa_thread_free(pa_thread *t) { - assert(t); + pa_assert(t); pa_thread_join(t); pa_xfree(t); } int pa_thread_join(pa_thread *t) { - assert(t); + pa_assert(t); return pthread_join(t->id, NULL); } @@ -137,9 +124,7 @@ int pa_thread_join(pa_thread *t) { pa_thread* pa_thread_self(void) { pa_thread *t; - pa_once(&thread_tls_once, thread_tls_once_func); - - if ((t = pa_tls_get(thread_tls))) + if ((t = PA_STATIC_TLS_GET(current_thread))) return t; /* This is a foreign thread, let's create a pthread structure to @@ -151,19 +136,19 @@ pa_thread* pa_thread_self(void) { t->userdata = NULL; pa_atomic_store(&t->running, 2); - pa_tls_set(thread_tls, t); + PA_STATIC_TLS_SET(current_thread, t); return t; } void* pa_thread_get_data(pa_thread *t) { - assert(t); + pa_assert(t); return t->userdata; } void pa_thread_set_data(pa_thread *t, void *userdata) { - assert(t); + pa_assert(t); t->userdata = userdata; } @@ -172,7 +157,7 @@ void pa_thread_yield(void) { #ifdef HAVE_PTHREAD_YIELD pthread_yield(); #else - ASSERT_SUCCESS(sched_yield()); + pa_assert_se(sched_yield() == 0); #endif } @@ -190,14 +175,14 @@ pa_tls* pa_tls_new(pa_free_cb_t free_cb) { } void pa_tls_free(pa_tls *t) { - assert(t); + pa_assert(t); - ASSERT_SUCCESS(pthread_key_delete(t->key)); + pa_assert_se(pthread_key_delete(t->key) == 0); pa_xfree(t); } void *pa_tls_get(pa_tls *t) { - assert(t); + pa_assert(t); return pthread_getspecific(t->key); } @@ -206,7 +191,7 @@ void *pa_tls_set(pa_tls *t, void *userdata) { void *r; r = pthread_getspecific(t->key); - ASSERT_SUCCESS(pthread_setspecific(t->key, userdata)); + pa_assert_se(pthread_setspecific(t->key, userdata) == 0); return r; } -- cgit