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.
This commit is contained in:
wm4 2014-10-24 21:52:16 +02:00
parent b330f16fed
commit 55e3dab7eb
3 changed files with 33 additions and 6 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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)