jack: release lock when doing do_sync from data thread

If we do_sync from the data thread, release the rt_lock so that any
callbacks that may happen while waiting can grab the rt_lock.

We could also temporarily disable the rt_lock grabbing before the
callbacks.

In any case the callbacks will need to be called while we execute
the blocking function in the process callback.
This commit is contained in:
Wim Taymans 2022-02-10 17:13:48 +01:00
parent f636603844
commit f123b58f1f

View file

@ -378,6 +378,7 @@ struct client {
} rt; } rt;
pthread_mutex_t rt_lock; pthread_mutex_t rt_lock;
unsigned int rt_locked:1;
unsigned int started:1; unsigned int started:1;
unsigned int active:1; unsigned int active:1;
@ -807,7 +808,9 @@ void jack_get_version(int *major_ptr, int *minor_ptr, int *micro_ptr, int *proto
int res = 0; \ int res = 0; \
if (c->callback) { \ if (c->callback) { \
if (pthread_mutex_trylock(&c->rt_lock) == 0) { \ if (pthread_mutex_trylock(&c->rt_lock) == 0) { \
c->rt_locked = true; \
res = c->callback(__VA_ARGS__); \ res = c->callback(__VA_ARGS__); \
c->rt_locked = false; \
pthread_mutex_unlock(&c->rt_lock); \ pthread_mutex_unlock(&c->rt_lock); \
} \ } \
} \ } \
@ -858,6 +861,8 @@ static const struct pw_core_events core_events = {
static int do_sync(struct client *client) static int do_sync(struct client *client)
{ {
bool in_data_thread = pw_data_loop_in_thread(client->loop);
if (pw_thread_loop_in_thread(client->context.loop)) { if (pw_thread_loop_in_thread(client->context.loop)) {
pw_log_warn("sync requested from callback"); pw_log_warn("sync requested from callback");
return 0; return 0;
@ -868,8 +873,14 @@ static int do_sync(struct client *client)
client->pending_sync = pw_proxy_sync((struct pw_proxy*)client->core, client->pending_sync); client->pending_sync = pw_proxy_sync((struct pw_proxy*)client->core, client->pending_sync);
while (true) { while (true) {
if (in_data_thread && client->rt_locked)
pthread_mutex_unlock(&client->rt_lock);
pw_thread_loop_wait(client->context.loop); pw_thread_loop_wait(client->context.loop);
if (in_data_thread && client->rt_locked)
pthread_mutex_lock(&client->rt_lock);
if (client->error) if (client->error)
return client->last_res; return client->last_res;