summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2020-01-16 13:27:52 +0100
committerWim Taymans <wtaymans@redhat.com>2020-01-16 13:27:52 +0100
commit940aba862367296e78b7bac03887dcfe49949464 (patch)
tree279873f0b5b42e7411a92c7747dc617142d257bc
parentbac6bf090cdc239f9e9641d3fbfe4a2db069d1e1 (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.c41
-rw-r--r--src/pipewire/private.h2
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;