client API: call wakeup callback if there are new messages

Listening on messages currently uses polling (every time
mpv_wait_event() has no new events, the message buffer is polled and a
message event is possibly created). Improve this situation a bit, and
call the user-supplied wakeup callback.

This will increase the frequency with which the wakeup callback is
called, but the client is already supposed to be able to deal with this
situation. Also, as before, calling mpv_wait_event() from the wakeup
callback is forbidden, so the client can't read new messages from the
callback directly.

The wakeup pipe is written either. Since the wakeup pipe is created
lazily, we can't access the pipe handle without creating a race
condition or a deadlock. (This is actually very silly, since in practice
the race condition won't matter, but for now let's keep it clean.)
This commit is contained in:
wm4 2014-06-06 19:24:30 +02:00
parent 79e76abb4d
commit 3b7402b51c
3 changed files with 29 additions and 15 deletions

View File

@ -82,6 +82,8 @@ struct mp_log_buffer {
struct mp_log_root *root;
struct mp_ring *ring;
int level;
void (*wakeup_cb)(void *ctx);
void *wakeup_cb_ctx;
};
// Protects some (not all) state in mp_log_root
@ -319,6 +321,8 @@ static void write_msg_to_buffers(struct mp_log *log, int lev, char *text)
};
}
mp_ring_write(buffer->ring, (unsigned char *)&entry, sizeof(entry));
if (buffer->wakeup_cb)
buffer->wakeup_cb(buffer->wakeup_cb_ctx);
}
}
}
@ -459,7 +463,9 @@ void mp_msg_uninit(struct mpv_global *global)
}
struct mp_log_buffer *mp_msg_log_buffer_new(struct mpv_global *global,
int size, int level)
int size, int level,
void (*wakeup_cb)(void *ctx),
void *wakeup_cb_ctx)
{
struct mp_log_root *root = global->log->root;
@ -470,6 +476,8 @@ struct mp_log_buffer *mp_msg_log_buffer_new(struct mpv_global *global,
.root = root,
.level = level,
.ring = mp_ring_new(buffer, sizeof(void *) * size),
.wakeup_cb = wakeup_cb,
.wakeup_cb_ctx = wakeup_cb_ctx,
};
if (!buffer->ring)
abort();

View File

@ -20,7 +20,9 @@ struct mp_log_buffer_entry {
struct mp_log_buffer;
struct mp_log_buffer *mp_msg_log_buffer_new(struct mpv_global *global,
int size, int level);
int size, int level,
void (*wakeup_cb)(void *ctx),
void *wakeup_cb_ctx);
void mp_msg_log_buffer_destroy(struct mp_log_buffer *buffer);
struct mp_log_buffer_entry *mp_msg_log_buffer_read(struct mp_log_buffer *buffer);

View File

@ -114,6 +114,7 @@ struct mpv_handle {
};
static bool gen_property_change_event(struct mpv_handle *ctx);
static void recreate_message_buffer(mpv_handle *ctx);
void mp_clients_init(struct MPContext *mpctx)
{
@ -226,6 +227,8 @@ void mpv_set_wakeup_callback(mpv_handle *ctx, void (*cb)(void *d), void *d)
pthread_mutex_lock(&ctx->lock);
ctx->wakeup_cb = cb;
ctx->wakeup_cb_ctx = d;
// Update the message callback
recreate_message_buffer(ctx);
pthread_mutex_unlock(&ctx->lock);
}
@ -1240,6 +1243,18 @@ int mpv_load_config_file(mpv_handle *ctx, const char *filename)
return 0;
}
// called locked
static void recreate_message_buffer(mpv_handle *ctx)
{
mp_msg_log_buffer_destroy(ctx->messages);
ctx->messages = NULL;
if (ctx->messages_level >= 0) {
ctx->messages =
mp_msg_log_buffer_new(ctx->mpctx->global, 1000, ctx->messages_level,
ctx->wakeup_cb, ctx->wakeup_cb_ctx);
}
}
int mpv_request_log_messages(mpv_handle *ctx, const char *min_level)
{
int level = -1;
@ -1253,19 +1268,8 @@ int mpv_request_log_messages(mpv_handle *ctx, const char *min_level)
return MPV_ERROR_INVALID_PARAMETER;
pthread_mutex_lock(&ctx->lock);
if (!ctx->messages)
ctx->messages_level = -1;
if (ctx->messages_level != level) {
mp_msg_log_buffer_destroy(ctx->messages);
ctx->messages = NULL;
if (level >= 0) {
ctx->messages =
mp_msg_log_buffer_new(ctx->mpctx->global, 1000, level);
}
ctx->messages_level = level;
}
ctx->messages_level = level;
recreate_message_buffer(ctx);
pthread_mutex_unlock(&ctx->lock);
return 0;