From 55e3dab7ebd707a94995696aa1098725f3c35521 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 24 Oct 2014 21:52:16 +0200 Subject: command: finish hook execution if client fails Translation: if the (to be added) youtube-dl Lua script crashes, don't wait forever when opening something. --- player/client.c | 11 ++++++++++- player/client.h | 1 + player/command.c | 27 ++++++++++++++++++++++----- 3 files changed, 33 insertions(+), 6 deletions(-) (limited to 'player') 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) -- cgit v1.2.3