diff options
Diffstat (limited to 'player/client.c')
-rw-r--r-- | player/client.c | 71 |
1 files changed, 36 insertions, 35 deletions
diff --git a/player/client.c b/player/client.c index 411d634100..f1e824fc5d 100644 --- a/player/client.c +++ b/player/client.c @@ -416,6 +416,32 @@ int mpv_initialize(mpv_handle *ctx) return 0; } +// set ev->data to a new copy of the original data +// (done only for message types that are broadcast) +static void dup_event_data(struct mpv_event *ev) +{ + switch (ev->event_id) { + case MPV_EVENT_CLIENT_MESSAGE: { + struct mpv_event_client_message *src = ev->data; + struct mpv_event_client_message *msg = + talloc_zero(NULL, struct mpv_event_client_message); + for (int n = 0; n < src->num_args; n++) { + MP_TARRAY_APPEND(msg, msg->args, msg->num_args, + talloc_strdup(msg, src->args[n])); + } + ev->data = msg; + break; + } + case MPV_EVENT_END_FILE: + ev->data = talloc_memdup(NULL, ev->data, sizeof(mpv_event_end_file)); + break; + default: + // Doesn't use events with memory allocation. + if (ev->data) + abort(); + } +} + // Reserve an entry in the ring buffer. This can be used to guarantee that the // reply can be made, even if the buffer becomes congested _after_ sending // the request. @@ -432,17 +458,19 @@ static int reserve_reply(struct mpv_handle *ctx) return res; } -static int append_event(struct mpv_handle *ctx, struct mpv_event *event) +static int append_event(struct mpv_handle *ctx, struct mpv_event event, bool copy) { if (ctx->num_events + ctx->reserved_events >= ctx->max_events) return -1; - ctx->events[(ctx->first_event + ctx->num_events) % ctx->max_events] = *event; + if (copy) + dup_event_data(&event); + ctx->events[(ctx->first_event + ctx->num_events) % ctx->max_events] = event; ctx->num_events++; wakeup_client(ctx); return 0; } -static int send_event(struct mpv_handle *ctx, struct mpv_event *event) +static int send_event(struct mpv_handle *ctx, struct mpv_event *event, bool copy) { pthread_mutex_lock(&ctx->lock); uint64_t mask = 1ULL << event->event_id; @@ -452,7 +480,7 @@ static int send_event(struct mpv_handle *ctx, struct mpv_event *event) pthread_mutex_unlock(&ctx->lock); return 0; } - int r = append_event(ctx, event); + int r = append_event(ctx, *event, copy); if (r < 0 && !ctx->choke_warning) { mp_err(ctx->log, "Too many events queued.\n"); ctx->choke_warning = true; @@ -471,8 +499,8 @@ static void send_reply(struct mpv_handle *ctx, uint64_t userdata, // If this fails, reserve_reply() probably wasn't called. assert(ctx->reserved_events > 0); ctx->reserved_events--; - if (append_event(ctx, event) < 0) - abort(); + if (append_event(ctx, *event, false) < 0) + abort(); // not reached pthread_mutex_unlock(&ctx->lock); } @@ -486,32 +514,6 @@ static void status_reply(struct mpv_handle *ctx, int event, send_reply(ctx, userdata, &reply); } -// set ev->data to a new copy of the original data -// (done only for message types that are broadcast) -static void dup_event_data(struct mpv_event *ev) -{ - switch (ev->event_id) { - case MPV_EVENT_CLIENT_MESSAGE: { - struct mpv_event_client_message *src = ev->data; - struct mpv_event_client_message *msg = - talloc_zero(NULL, struct mpv_event_client_message); - for (int n = 0; n < src->num_args; n++) { - MP_TARRAY_APPEND(msg, msg->args, msg->num_args, - talloc_strdup(msg, src->args[n])); - } - ev->data = msg; - break; - } - case MPV_EVENT_END_FILE: - ev->data = talloc_memdup(NULL, ev->data, sizeof(mpv_event_end_file)); - break; - default: - // Doesn't use events with memory allocation. - if (ev->data) - abort(); - } -} - // Return whether there's any client listening to this event. // If false is returned, the core doesn't need to send it. bool mp_client_event_is_registered(struct MPContext *mpctx, int event) @@ -546,8 +548,7 @@ void mp_client_broadcast_event(struct MPContext *mpctx, int event, void *data) .event_id = event, .data = data, }; - dup_event_data(&event_data); - send_event(clients->clients[n], &event_data); + send_event(clients->clients[n], &event_data, true); } pthread_mutex_unlock(&clients->lock); @@ -568,7 +569,7 @@ int mp_client_send_event(struct MPContext *mpctx, const char *client_name, struct mpv_handle *ctx = find_client(clients, client_name); if (ctx) { - r = send_event(ctx, &event_data); + r = send_event(ctx, &event_data, false); } else { r = -1; talloc_free(data); |