diff options
author | Wim Taymans <wtaymans@redhat.com> | 2020-01-16 13:27:52 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2020-01-16 13:27:52 +0100 |
commit | 940aba862367296e78b7bac03887dcfe49949464 (patch) | |
tree | 279873f0b5b42e7411a92c7747dc617142d257bc | |
parent | bac6bf090cdc239f9e9641d3fbfe4a2db069d1e1 (diff) |
data-loop: use pthread_cancel to stop thread
Use pthread_cancel to terminate the data threads. We need this for
jack support but it's generally useful for a data thread.
-rw-r--r-- | src/pipewire/data-loop.c | 41 | ||||
-rw-r--r-- | src/pipewire/private.h | 2 |
2 files changed, 17 insertions, 26 deletions
diff --git a/src/pipewire/data-loop.c b/src/pipewire/data-loop.c index ad146048..9446b217 100644 --- a/src/pipewire/data-loop.c +++ b/src/pipewire/data-loop.c @@ -55,6 +55,14 @@ void pw_data_loop_exit(struct pw_data_loop *this) this->running = false; } +static void thread_cleanup(void *arg) +{ + struct pw_data_loop *this = arg; + pw_log_debug(NAME" %p: leave thread", this); + this->running = false; + pw_loop_enter(this->loop); +} + static void *do_loop(void *user_data) { struct pw_data_loop *this = user_data; @@ -63,6 +71,8 @@ static void *do_loop(void *user_data) pw_log_debug(NAME" %p: enter thread", this); pw_loop_enter(this->loop); + pthread_cleanup_push(thread_cleanup, this); + while (this->running) { if ((res = pw_loop_iterate(this->loop, -1)) < 0) { if (errno == EINTR) @@ -71,21 +81,11 @@ static void *do_loop(void *user_data) this, res, spa_strerror(res)); } } - - pw_log_debug(NAME" %p: leave thread", this); - pw_loop_leave(this->loop); + pthread_cleanup_pop(1); return NULL; } - -static void do_stop(void *data, uint64_t count) -{ - struct pw_data_loop *this = data; - pw_log_debug(NAME" %p: stopping", this); - this->running = false; -} - static struct pw_data_loop *loop_new(struct pw_loop *loop, const struct spa_dict *props) { struct pw_data_loop *this; @@ -110,20 +110,10 @@ static struct pw_data_loop *loop_new(struct pw_loop *loop, const struct spa_dict } this->loop = loop; - this->event = pw_loop_add_event(this->loop, do_stop, this); - if (this->event == NULL) { - res = -errno; - pw_log_error(NAME" %p: can't add event: %m", this); - goto error_loop_destroy; - } - spa_hook_list_init(&this->listener_list); return this; -error_loop_destroy: - if (this->created && this->loop) - pw_loop_destroy(this->loop); error_free: free(this); error_cleanup: @@ -156,7 +146,6 @@ void pw_data_loop_destroy(struct pw_data_loop *loop) pw_data_loop_stop(loop); - pw_loop_destroy_source(loop->loop, loop->event); if (loop->created) pw_loop_destroy(loop->loop); free(loop); @@ -212,11 +201,15 @@ int pw_data_loop_start(struct pw_data_loop *loop) SPA_EXPORT int pw_data_loop_stop(struct pw_data_loop *loop) { + pw_log_debug(NAME": %p stopping", loop); if (loop->running) { - pw_loop_signal_event(loop->loop, loop->event); - + pw_log_debug(NAME": %p cancel", loop); + pthread_cancel(loop->thread); + pw_log_debug(NAME": %p join", loop); pthread_join(loop->thread, NULL); + pw_log_debug(NAME": %p joined", loop); } + pw_log_debug(NAME": %p stopped", loop); return 0; } diff --git a/src/pipewire/private.h b/src/pipewire/private.h index aa9163e8..4b22b792 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -282,8 +282,6 @@ struct pw_data_loop { struct spa_hook_list listener_list; - struct spa_source *event; - pthread_t thread; unsigned int created:1; unsigned int running:1; |