summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--player/client.c11
-rw-r--r--player/client.h1
-rw-r--r--player/command.c27
3 files changed, 33 insertions, 6 deletions
diff --git a/player/client.c b/player/client.c
index a150271df0..8376756a9a 100644
--- a/player/client.c
+++ b/player/client.c
@@ -187,6 +187,14 @@ static struct mpv_handle *find_client(struct mp_client_api *clients,
return NULL;
}
+bool mp_client_exists(struct MPContext *mpctx, const char *client_name)
+{
+ pthread_mutex_lock(&mpctx->clients->lock);
+ bool r = find_client(mpctx->clients, client_name);
+ pthread_mutex_unlock(&mpctx->clients->lock);
+ return r;
+}
+
struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name)
{
pthread_mutex_lock(&clients->lock);
@@ -348,7 +356,8 @@ void mpv_detach_destroy(mpv_handle *ctx)
}
talloc_free(ctx);
ctx = NULL;
- // shutdown_clients() sleeps to avoid wasting CPU
+ // shutdown_clients() sleeps to avoid wasting CPU.
+ // mp_hook_test_completion() also relies on this a bit.
if (clients->mpctx->input)
mp_input_wakeup(clients->mpctx->input);
break;
diff --git a/player/client.h b/player/client.h
index db248e0cef..14822504c9 100644
--- a/player/client.h
+++ b/player/client.h
@@ -16,6 +16,7 @@ void mp_clients_destroy(struct MPContext *mpctx);
int mp_clients_num(struct MPContext *mpctx);
bool mp_clients_all_initialized(struct MPContext *mpctx);
+bool mp_client_exists(struct MPContext *mpctx, const char *client_name);
void mp_client_broadcast_event(struct MPContext *mpctx, int event, void *data);
int mp_client_send_event(struct MPContext *mpctx, const char *client_name,
int event, void *data);
diff --git a/player/command.c b/player/command.c
index 1109e7ac7f..7584ef024e 100644
--- a/player/command.c
+++ b/player/command.c
@@ -112,13 +112,26 @@ static int edit_filters(struct MPContext *mpctx, enum stream_type mediatype,
static int set_filters(struct MPContext *mpctx, enum stream_type mediatype,
struct m_obj_settings *new_chain);
+static void hook_remove(struct MPContext *mpctx, int index)
+{
+ struct command_ctx *cmd = mpctx->command_ctx;
+ assert(index >= 0 && index < cmd->num_hooks);
+ talloc_free(cmd->hooks[index]);
+ MP_TARRAY_REMOVE_AT(cmd->hooks, cmd->num_hooks, index);
+}
+
bool mp_hook_test_completion(struct MPContext *mpctx, char *type)
{
struct command_ctx *cmd = mpctx->command_ctx;
for (int n = 0; n < cmd->num_hooks; n++) {
struct hook_handler *h = cmd->hooks[n];
- if (h->active && strcmp(h->type, type) == 0)
+ if (h->active && strcmp(h->type, type) == 0) {
+ if (!mp_client_exists(mpctx, h->client)) {
+ hook_remove(mpctx, n);
+ break;
+ }
return false;
+ }
}
return true;
}
@@ -142,8 +155,8 @@ static bool send_hook_msg(struct MPContext *mpctx, struct hook_handler *h,
void mp_hook_run(struct MPContext *mpctx, char *client, char *type)
{
struct command_ctx *cmd = mpctx->command_ctx;
- struct hook_handler *next = NULL;
bool found_current = !client;
+ int index = -1;
for (int n = 0; n < cmd->num_hooks; n++) {
struct hook_handler *h = cmd->hooks[n];
if (!found_current) {
@@ -152,15 +165,19 @@ void mp_hook_run(struct MPContext *mpctx, char *client, char *type)
found_current = true;
}
} else if (strcmp(h->type, type) == 0) {
- next = h;
+ index = n;
break;
}
}
- if (!next)
+ if (index < 0)
return;
+ struct hook_handler *next = cmd->hooks[index];
MP_VERBOSE(mpctx, "Running hook: %s/%s\n", next->client, type);
next->active = true;
- send_hook_msg(mpctx, next, "hook_run");
+ if (!send_hook_msg(mpctx, next, "hook_run")) {
+ hook_remove(mpctx, index);
+ mp_input_wakeup(mpctx->input); // repeat next iteration to finish
+ }
}
static int compare_hook(const void *pa, const void *pb)