1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-26 00:42:57 +00:00

command: use client IDs for hooks

Removes weird potential race conditions when a client is removed and a
new one with the same name is created.
This commit is contained in:
wm4 2020-03-26 23:40:25 +01:00
parent ca34922130
commit 9bda301eb4
4 changed files with 24 additions and 12 deletions

View File

@ -262,6 +262,14 @@ bool mp_client_exists(struct MPContext *mpctx, const char *client_name)
return r;
}
bool mp_client_id_exists(struct MPContext *mpctx, int64_t id)
{
pthread_mutex_lock(&mpctx->clients->lock);
bool r = find_client_id(mpctx->clients, id);
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);
@ -1825,7 +1833,7 @@ int mpv_hook_add(mpv_handle *ctx, uint64_t reply_userdata,
const char *name, int priority)
{
lock_core(ctx);
mp_hook_add(ctx->mpctx, ctx->name, name, reply_userdata, priority);
mp_hook_add(ctx->mpctx, ctx->name, ctx->id, name, reply_userdata, priority);
unlock_core(ctx);
return 0;
}
@ -1833,7 +1841,7 @@ int mpv_hook_add(mpv_handle *ctx, uint64_t reply_userdata,
int mpv_hook_continue(mpv_handle *ctx, uint64_t id)
{
lock_core(ctx);
int r = mp_hook_continue(ctx->mpctx, ctx->name, id);
int r = mp_hook_continue(ctx->mpctx, ctx->id, id);
unlock_core(ctx);
return r;
}

View File

@ -24,6 +24,7 @@ bool mp_is_shutting_down(struct MPContext *mpctx);
bool mp_clients_all_initialized(struct MPContext *mpctx);
bool mp_client_exists(struct MPContext *mpctx, const char *client_name);
bool mp_client_id_exists(struct MPContext *mpctx, int64_t id);
void mp_client_broadcast_event(struct MPContext *mpctx, int event, void *data);
int mp_client_send_event(struct MPContext *mpctx, const char *client_name,
uint64_t reply_userdata, int event, void *data);

View File

@ -118,7 +118,8 @@ struct overlay {
};
struct hook_handler {
char *client; // client API user name
char *client; // client mpv_handle name (for logging)
int64_t client_id; // client mpv_handle ID
char *type; // kind of hook, e.g. "on_load"
uint64_t user_id; // user-chosen ID
int priority; // priority for global hook order
@ -160,7 +161,7 @@ bool mp_hook_test_completion(struct MPContext *mpctx, char *type)
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 (!mp_client_exists(mpctx, h->client)) {
if (!mp_client_id_exists(mpctx, h->client_id)) {
MP_WARN(mpctx, "client removed during hook handling\n");
hook_remove(mpctx, h);
break;
@ -183,7 +184,8 @@ static int invoke_hook_handler(struct MPContext *mpctx, struct hook_handler *h)
.id = h->seq,
},
reply_id = h->user_id;
int r = mp_client_send_event(mpctx, h->client, reply_id, MPV_EVENT_HOOK, m);
char *name = mp_tprintf(22, "@%"PRIi64, h->client_id);
int r = mp_client_send_event(mpctx, name, reply_id, MPV_EVENT_HOOK, m);
if (r < 0) {
MP_WARN(mpctx, "Sending hook command failed. Removing hook.\n");
hook_remove(mpctx, h);
@ -216,13 +218,13 @@ void mp_hook_start(struct MPContext *mpctx, char *type)
}
}
int mp_hook_continue(struct MPContext *mpctx, char *client, uint64_t id)
int mp_hook_continue(struct MPContext *mpctx, int64_t client_id, uint64_t id)
{
struct command_ctx *cmd = mpctx->command_ctx;
for (int n = 0; n < cmd->num_hooks; n++) {
struct hook_handler *h = cmd->hooks[n];
if (strcmp(h->client, client) == 0 && h->seq == id) {
if (h->client_id == client_id && h->seq == id) {
if (!h->active)
break;
h->active = false;
@ -243,14 +245,15 @@ static int compare_hook(const void *pa, const void *pb)
return (*h1)->seq - (*h2)->seq;
}
void mp_hook_add(struct MPContext *mpctx, const char *client, const char *name,
uint64_t user_id, int pri)
void mp_hook_add(struct MPContext *mpctx, char *client, int64_t client_id,
const char *name, uint64_t user_id, int pri)
{
struct command_ctx *cmd = mpctx->command_ctx;
struct hook_handler *h = talloc_ptrtype(cmd, h);
int64_t seq = ++cmd->hook_seq;
*h = (struct hook_handler){
.client = talloc_strdup(h, client),
.client_id = client_id,
.type = talloc_strdup(h, name),
.user_id = user_id,
.priority = pri,

View File

@ -105,9 +105,9 @@ enum {
bool mp_hook_test_completion(struct MPContext *mpctx, char *type);
void mp_hook_start(struct MPContext *mpctx, char *type);
int mp_hook_continue(struct MPContext *mpctx, char *client, uint64_t id);
void mp_hook_add(struct MPContext *mpctx, const char *client, const char *name,
uint64_t user_id, int pri);
int mp_hook_continue(struct MPContext *mpctx, int64_t client_id, uint64_t id);
void mp_hook_add(struct MPContext *mpctx, char *client, int64_t client_id,
const char *name, uint64_t user_id, int pri);
void mark_seek(struct MPContext *mpctx);