static void thread_func(void *data) { pa_tls_set(tls, data); pa_log_info("thread_func() for %s starting...", (char*) pa_tls_get(tls)); pa_mutex_lock(mutex); for (;;) { int k, n; pa_log_info("%s waiting ...", (char*) pa_tls_get(tls)); for (;;) { if (magic_number < 0) goto quit; if (magic_number != 0) break; pa_cond_wait(cond1, mutex); } k = magic_number; magic_number = 0; pa_mutex_unlock(mutex); pa_run_once(&once, once_func); pa_cond_signal(cond2, 0); pa_log_info("%s got number %i", (char*) pa_tls_get(tls), k); /* Spin! */ for (n = 0; n < k; n++) pa_thread_yield(); pa_mutex_lock(mutex); } quit: pa_mutex_unlock(mutex); pa_log_info("thread_func() for %s done...", (char*) pa_tls_get(tls)); }
void *pa_tls_set(pa_tls *t, void *userdata) { void *r; assert(t); r = TlsGetValue(t->index); TlsSetValue(t->index, userdata); if (t->free_func) { struct pa_tls_monitor *m; PA_ONCE_BEGIN { monitor_tls = pa_tls_new(NULL); assert(monitor_tls); pa_tls_set(monitor_tls, NULL); } PA_ONCE_END; m = pa_tls_get(monitor_tls); if (!m) { HANDLE thread; m = pa_xnew(struct pa_tls_monitor, 1); DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &m->thread, 0, FALSE, DUPLICATE_SAME_ACCESS); m->free_func = t->free_func; pa_tls_set(monitor_tls, m); thread = CreateThread(NULL, 0, monitor_thread_func, m, 0, NULL); assert(thread); CloseHandle(thread); } m->data = userdata; }
pa_thread* pa_thread_self(void) { pa_run_once(&thread_tls_once, thread_tls_once_func); return pa_tls_get(thread_tls); }