pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("alsa-sink", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("alsa-source", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
}
#endif
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("bluetooth", thread_func, u))) {
pa_log_error("Failed to create IO thread");
stop_thread(u);
return -1;
return pa_sink_process_msg(o, code, data, offset, memchunk);
}
+/* JACK Callback: This is called when JACK needs some data */
static int jack_process(jack_nframes_t nframes, void *arg) {
struct userdata *u = arg;
unsigned c;
pa_log_debug("Thread shutting down");
}
+/* JACK Callback: This is called when JACK triggers an error */
static void jack_error_func(const char*t) {
char *s;
pa_xfree(s);
}
+/* JACK Callback: This is called when JACK is set up */
static void jack_init(void *arg) {
struct userdata *u = arg;
pa_make_realtime(u->core->realtime_priority+4);
}
+/* JACK Callback: This is called when JACK kicks us */
static void jack_shutdown(void* arg) {
struct userdata *u = arg;
pa_asyncmsgq_post(u->jack_msgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_ON_SHUTDOWN, NULL, 0, NULL, NULL);
}
+/* JACK Callback: This is called when JACK changes the buffer size */
static int jack_buffer_size(jack_nframes_t nframes, void *arg) {
struct userdata *u = arg;
jack_set_thread_init_callback(u->client, jack_init, u);
jack_set_buffer_size_callback(u->client, jack_buffer_size, u);
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("jack-sink", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
jack_on_shutdown(u->client, jack_shutdown, u);
jack_set_thread_init_callback(u->client, jack_init, u);
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("jack-source", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_hook_cb, u);
u->sink_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_state_changed_hook_cb, u);
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("combine", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
/* Reserve space for the response */
u->read_data = pa_xmalloc(u->read_length = sizeof(int32_t));
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("esound-sink", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
pa_sink_set_max_rewind(u->sink, nbytes);
pa_sink_set_max_request(u->sink, nbytes);
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("null-sink", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
pollfd->fd = u->fd;
pollfd->events = pollfd->revents = 0;
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("pipe-sink", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
pollfd->fd = u->fd;
pollfd->events = pollfd->revents = 0;
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("pipe-source", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
pa_source_set_rtpoll(u->source, u->rtpoll);
pa_source_set_fixed_latency(u->source, u->block_usec);
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("sine-source", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
u->fragsize = (uint32_t) -1;
#endif
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("module-tunnel", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
pa_memchunk_reset(&u->memchunk);
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("oss", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
pa_raop_client_set_callback(u->raop, on_connection, u);
pa_raop_client_set_closed_callback(u->raop, on_close, u);
- if (!(u->thread = pa_thread_new(thread_func, u))) {
+ if (!(u->thread = pa_thread_new("raop-sink", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
pa_assert(!m->thread || !pa_thread_is_running(m->thread));
- if (!(m->thread = pa_thread_new(thread, m)))
+ if (!(m->thread = pa_thread_new("threaded-ml", thread, m)))
return -1;
return 0;
static int start_thread(void) {
if (!thread)
- if (!(thread = pa_thread_new(thread_func, NULL)))
+ if (!(thread = pa_thread_new("autospawn", thread_func, NULL)))
return -1;
return 0;
#include <sched.h>
#include <errno.h>
+#ifdef __linux__
+#include <sys/prctl.h>
+#endif
+
#include <pulse/xmalloc.h>
#include <pulsecore/mutex.h>
#include <pulsecore/once.h>
void *userdata;
pa_atomic_t running;
pa_bool_t joined;
+ char *name;
};
struct pa_tls {
pa_assert(t);
- if (!t->thread_func)
+ if (!t->thread_func) {
/* This is a foreign thread, we need to free the struct */
+ pa_xfree(t->name);
pa_xfree(t);
+ }
}
PA_STATIC_TLS_DECLARE(current_thread, thread_free_cb);
pa_thread *t = userdata;
pa_assert(t);
+#ifdef __linux__
+ prctl(PR_SET_NAME, t->name);
+#endif
+
t->id = pthread_self();
PA_STATIC_TLS_SET(current_thread, t);
return NULL;
}
-pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) {
+pa_thread* pa_thread_new(const char *name, pa_thread_func_t thread_func, void *userdata) {
pa_thread *t;
pa_assert(thread_func);
t = pa_xnew0(pa_thread, 1);
+ t->name = pa_xstrdup(name);
t->thread_func = thread_func;
t->userdata = userdata;
pa_assert(t);
pa_thread_join(t);
+
+ pa_xfree(t->name);
pa_xfree(t);
}
t->userdata = userdata;
}
+void pa_thread_set_name(pa_thread *t, const char *name) {
+ pa_assert(t);
+
+ pa_xfree(t->name);
+ t->name = pa_xstrdup(name);
+
+#ifdef __linux__
+ prctl(PR_SET_NAME, name);
+#endif
+}
+
+const char *pa_thread_get_name(pa_thread *t) {
+ pa_assert(t);
+
+#ifdef __linux__
+ if (!t->name) {
+ t->name = pa_xmalloc(17);
+
+ if (prctl(PR_GET_NAME, t->name) >= 0)
+ t->name[16] = 0;
+ else {
+ pa_xfree(t->name);
+ t->name = NULL;
+ }
+ }
+#endif
+
+ return t->name;
+}
+
void pa_thread_yield(void) {
#ifdef HAVE_PTHREAD_YIELD
pthread_yield();
typedef void (*pa_thread_func_t) (void *userdata);
-pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata);
+pa_thread* pa_thread_new(const char *name, pa_thread_func_t thread_func, void *userdata);
void pa_thread_free(pa_thread *t);
int pa_thread_join(pa_thread *t);
int pa_thread_is_running(pa_thread *t);
void* pa_thread_get_data(pa_thread *t);
void pa_thread_set_data(pa_thread *t, void *userdata);
+const char *pa_thread_get_name(pa_thread *t);
+void pa_thread_set_name(pa_thread *t, const char *name);
+
typedef struct pa_tls pa_tls;
pa_tls* pa_tls_new(pa_free_cb_t free_cb);
pa_assert_se(q = pa_asyncmsgq_new(0));
- pa_assert_se(t = pa_thread_new(the_thread, q));
+ pa_assert_se(t = pa_thread_new("test", the_thread, q));
printf("Operation A post\n");
pa_asyncmsgq_post(q, NULL, OPERATION_A, NULL, 0, NULL, NULL);
pa_assert_se(q = pa_asyncq_new(0));
- pa_assert_se(t1 = pa_thread_new(producer, q));
- pa_assert_se(t2 = pa_thread_new(consumer, q));
+ pa_assert_se(t1 = pa_thread_new("producer", producer, q));
+ pa_assert_se(t2 = pa_thread_new("consumer", consumer, q));
pa_thread_free(t1);
pa_thread_free(t2);
flist = pa_flist_new(0);
for (i = 0; i < THREADS_MAX; i++) {
- threads[i] = pa_thread_new(thread_func, pa_sprintf_malloc("Thread #%i", i+1));
+ threads[i] = pa_thread_new("test", thread_func, pa_sprintf_malloc("Thread #%i", i+1));
assert(threads[i]);
}
int main(int argc, char**argv) {
pa_thread *a, *b, *c, *d;
- pa_assert_se((a = pa_thread_new(thread_func, PA_INT_TO_PTR(1))));
- pa_assert_se((b = pa_thread_new(thread_func2, PA_INT_TO_PTR(2))));
- pa_assert_se((c = pa_thread_new(thread_func2, PA_INT_TO_PTR(3))));
- pa_assert_se((d = pa_thread_new(thread_func, PA_INT_TO_PTR(4))));
+ pa_assert_se((a = pa_thread_new("test1", thread_func, PA_INT_TO_PTR(1))));
+ pa_assert_se((b = pa_thread_new("test2", thread_func2, PA_INT_TO_PTR(2))));
+ pa_assert_se((c = pa_thread_new("test3", thread_func2, PA_INT_TO_PTR(3))));
+ pa_assert_se((d = pa_thread_new("test4", thread_func, PA_INT_TO_PTR(4))));
pa_thread_join(a);
pa_thread_join(b);
tls = pa_tls_new(pa_xfree);
for (i = 0; i < THREADS_MAX; i++) {
- t[i] = pa_thread_new(thread_func, pa_sprintf_malloc("Thread #%i", i+1));
+ t[i] = pa_thread_new("test", thread_func, pa_sprintf_malloc("Thread #%i", i+1));
assert(t[i]);
}