summaryrefslogtreecommitdiffstats
path: root/player/client.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-01-19 19:54:20 +0100
committerwm4 <wm4@nowhere>2015-01-19 21:26:42 +0100
commit64f72687ce4227fc5e6f3636c8fd0078a8e098a2 (patch)
treedf27ca9566e18837a49d5320e50bb7beb73e29d3 /player/client.c
parentffaf4af230b92eb94fdf31784ca323cc931822e3 (diff)
downloadmpv-64f72687ce4227fc5e6f3636c8fd0078a8e098a2.tar.bz2
mpv-64f72687ce4227fc5e6f3636c8fd0078a8e098a2.tar.xz
client API: notify API user on event queue overflow
Before this, we merely printed a message to the terminal. Now the API user can determine this properly. This might be important for API users which somehow maintain complex state, which all has to be invalidated if (state-changing) events are missing due to an overflow. This also forces the client API user to empty the event queue, which is good, because otherwise the event queue would reach the "filled up" state immediately again due to further asynchronous events being added to the queue. Also add some minor improvements to mpv_wait_event() documentation, and some other minor cosmetic changes.
Diffstat (limited to 'player/client.c')
-rw-r--r--player/client.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/player/client.c b/player/client.c
index 50daf45393..c4f02b84c8 100644
--- a/player/client.c
+++ b/player/client.c
@@ -107,7 +107,6 @@ struct mpv_handle {
uint64_t event_mask;
bool queued_wakeup;
- bool choke_warning;
int suspend_count;
mpv_event *events; // ringbuffer of max_events entries
@@ -115,6 +114,7 @@ struct mpv_handle {
int first_event; // events[first_event] is the first readable event
int num_events; // number of readable events
int reserved_events; // number of entries reserved for replies
+ bool choked; // recovering from queue overflow
struct observe_property **properties;
int num_properties;
@@ -541,7 +541,8 @@ static int reserve_reply(struct mpv_handle *ctx)
{
int res = MPV_ERROR_EVENT_QUEUE_FULL;
pthread_mutex_lock(&ctx->lock);
- if (ctx->reserved_events + ctx->num_events < ctx->max_events) {
+ if (ctx->reserved_events + ctx->num_events < ctx->max_events && !ctx->choked)
+ {
ctx->reserved_events++;
res = 0;
}
@@ -567,14 +568,17 @@ static int send_event(struct mpv_handle *ctx, struct mpv_event *event, bool copy
uint64_t mask = 1ULL << event->event_id;
if (ctx->property_event_masks & mask)
notify_property_events(ctx, mask);
+ int r;
if (!(ctx->event_mask & mask)) {
- pthread_mutex_unlock(&ctx->lock);
- return 0;
- }
- 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;
+ r = 0;
+ } else if (ctx->choked) {
+ r = -1;
+ } else {
+ r = append_event(ctx, *event, copy);
+ if (r < 0) {
+ MP_ERR(ctx, "Too many events queued.\n");
+ ctx->choked = true;
+ }
}
pthread_mutex_unlock(&ctx->lock);
return r;
@@ -729,6 +733,12 @@ mpv_event *mpv_wait_event(mpv_handle *ctx, double timeout)
while (1) {
if (ctx->queued_wakeup)
deadline = 0;
+ // Recover from overflow.
+ if (ctx->choked && !ctx->num_events) {
+ ctx->choked = false;
+ event->event_id = MPV_EVENT_QUEUE_OVERFLOW;
+ break;
+ }
// This will almost surely lead to a deadlock. (Polling is still ok.)
if (ctx->suspend_count && timeout > 0) {
MP_ERR(ctx, "attempting to wait while core is suspended");
@@ -741,10 +751,11 @@ mpv_event *mpv_wait_event(mpv_handle *ctx, double timeout)
talloc_steal(event, event->data);
break;
}
+ // If there's a changed property, generate change event (never queued).
if (gen_property_change_event(ctx))
break;
+ // Pop item from message queue, and return as event.
if (ctx->messages) {
- // Poll the log message queue. Currently we can't/don't do better.
struct mp_log_buffer_entry *msg =
mp_msg_log_buffer_read(ctx->messages);
if (msg) {
@@ -1608,6 +1619,7 @@ static const char *const event_table[] = {
[MPV_EVENT_PLAYBACK_RESTART] = "playback-restart",
[MPV_EVENT_PROPERTY_CHANGE] = "property-change",
[MPV_EVENT_CHAPTER_CHANGE] = "chapter-change",
+ [MPV_EVENT_QUEUE_OVERFLOW] = "event-queue-overflow",
};
const char *mpv_event_name(mpv_event_id event)