summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-04-05 23:20:30 +0200
committerwm4 <wm4@nowhere>2014-04-06 03:22:49 +0200
commit14eb233da98bbac1c606e392e658f400deb5024b (patch)
tree6a8fb545e46de34e5762e264d167c9dbc153cdd4 /player
parentaa77f5dd3c5b4f064343f56ce59757e39768ab05 (diff)
downloadmpv-14eb233da98bbac1c606e392e658f400deb5024b.tar.bz2
mpv-14eb233da98bbac1c606e392e658f400deb5024b.tar.xz
client API: use a manual ringbuffer
Remove the use of mp_ring and use a simple array and a bunch of variables instead. This is way less awkwad. The change in reserve_reply fixes incorrect tracking of free events.
Diffstat (limited to 'player')
-rw-r--r--player/client.c62
1 files changed, 31 insertions, 31 deletions
diff --git a/player/client.c b/player/client.c
index 42d2fb2bb8..f33dcc2bf6 100644
--- a/player/client.c
+++ b/player/client.c
@@ -20,7 +20,6 @@
#include "common/msg.h"
#include "common/msg_control.h"
#include "input/input.h"
-#include "misc/ring.h"
#include "options/m_config.h"
#include "options/m_option.h"
#include "options/m_property.h"
@@ -63,9 +62,11 @@ struct mpv_handle {
void (*wakeup_cb)(void *d);
void *wakeup_cb_ctx;
- struct mp_ring *events; // stores mpv_event
- int max_events; // allocated number of entries in events
- int reserved_events; // number of entries reserved for replies
+ mpv_event *events; // ringbuffer of max_events entries
+ int max_events; // allocated number of entries in events
+ 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
struct mp_log_buffer *messages;
int messages_level;
@@ -138,7 +139,7 @@ struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name
.mpctx = clients->mpctx,
.clients = clients,
.cur_event = talloc_zero(client, struct mpv_event),
- .events = mp_ring_new(client, num_events * sizeof(struct mpv_event)),
+ .events = talloc_array(client, mpv_event, num_events),
.max_events = num_events,
.event_mask = ((uint64_t)-1) & ~(1ULL << MPV_EVENT_TICK),
};
@@ -194,7 +195,7 @@ void mpv_destroy(mpv_handle *ctx)
pthread_mutex_lock(&ctx->lock);
// reserved_events equals the number of asynchronous requests that weren't
- // yet replied. In order to avoid that trying to reply to a removed event
+ // yet replied. In order to avoid that trying to reply to a removed client
// causes a crash, block until all asynchronous requests were served.
ctx->event_mask = 0;
while (ctx->reserved_events)
@@ -207,12 +208,10 @@ void mpv_destroy(mpv_handle *ctx)
for (int n = 0; n < clients->num_clients; n++) {
if (clients->clients[n] == ctx) {
MP_TARRAY_REMOVE_AT(clients->clients, clients->num_clients, n);
- while (mp_ring_buffered(ctx->events)) {
- struct mpv_event event;
- int r = mp_ring_read(ctx->events, (unsigned char *)&event,
- sizeof(event));
- assert(r == sizeof(event));
- talloc_free(event.data);
+ while (ctx->num_events) {
+ talloc_free(ctx->events[ctx->first_event].data);
+ ctx->first_event = (ctx->first_event + 1) % ctx->max_events;
+ ctx->num_events--;
}
mp_msg_log_buffer_destroy(ctx->messages);
pthread_cond_destroy(&ctx->wakeup);
@@ -281,7 +280,7 @@ 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->max_events) {
+ if (ctx->reserved_events + ctx->num_events < ctx->max_events) {
ctx->reserved_events++;
res = 0;
}
@@ -289,6 +288,16 @@ static int reserve_reply(struct mpv_handle *ctx)
return res;
}
+static int append_event(struct mpv_handle *ctx, struct mpv_event *event)
+{
+ if (ctx->num_events + ctx->reserved_events >= ctx->max_events)
+ return -1;
+ 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)
{
pthread_mutex_lock(&ctx->lock);
@@ -296,20 +305,13 @@ static int send_event(struct mpv_handle *ctx, struct mpv_event *event)
pthread_mutex_unlock(&ctx->lock);
return 0;
}
- int num_events = mp_ring_available(ctx->events) / sizeof(*event);
- int r = 0;
- if (num_events > ctx->reserved_events) {
- r = mp_ring_write(ctx->events, (unsigned char *)event, sizeof(*event));
- if (r != sizeof(*event))
- abort();
- wakeup_client(ctx);
- }
- if (!r && !ctx->choke_warning) {
+ int r = append_event(ctx, event);
+ if (r < 0 && !ctx->choke_warning) {
mp_err(ctx->log, "Too many events queued.\n");
ctx->choke_warning = true;
}
pthread_mutex_unlock(&ctx->lock);
- return r ? 0 : -1;
+ return r;
}
// Send a reply; the reply must have been previously reserved with
@@ -319,12 +321,11 @@ static void send_reply(struct mpv_handle *ctx, uint64_t userdata,
{
event->reply_userdata = userdata;
pthread_mutex_lock(&ctx->lock);
+ // If this fails, reserve_reply() probably wasn't called.
assert(ctx->reserved_events > 0);
ctx->reserved_events--;
- int r = mp_ring_write(ctx->events, (unsigned char *)event, sizeof(*event));
- if (r != sizeof(*event))
+ if (append_event(ctx, event) < 0)
abort();
- wakeup_client(ctx);
pthread_mutex_unlock(&ctx->lock);
}
@@ -432,11 +433,10 @@ mpv_event *mpv_wait_event(mpv_handle *ctx, double timeout)
talloc_free_children(event);
while (1) {
- if (mp_ring_buffered(ctx->events)) {
- int r =
- mp_ring_read(ctx->events, (unsigned char*)event, sizeof(*event));
- if (r != sizeof(*event))
- abort();
+ if (ctx->num_events) {
+ *event = ctx->events[ctx->first_event];
+ ctx->first_event = (ctx->first_event + 1) % ctx->max_events;
+ ctx->num_events--;
talloc_steal(event, event->data);
break;
}