2014-01-16 20:24:39 +00:00
|
|
|
#ifndef MP_MSG_CONTROL_H
|
|
|
|
#define MP_MSG_CONTROL_H
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
2023-09-20 11:58:35 +00:00
|
|
|
#include "common/msg.h"
|
2014-01-16 20:24:39 +00:00
|
|
|
|
|
|
|
struct mpv_global;
|
2018-05-21 14:25:52 +00:00
|
|
|
struct MPOpts;
|
2014-01-16 20:24:39 +00:00
|
|
|
void mp_msg_init(struct mpv_global *global);
|
|
|
|
void mp_msg_uninit(struct mpv_global *global);
|
2018-05-21 14:25:52 +00:00
|
|
|
void mp_msg_update_msglevels(struct mpv_global *global, struct MPOpts *opts);
|
2014-01-16 20:24:39 +00:00
|
|
|
void mp_msg_force_stderr(struct mpv_global *global, bool force_stderr);
|
|
|
|
bool mp_msg_has_status_line(struct mpv_global *global);
|
2017-05-22 16:30:39 +00:00
|
|
|
bool mp_msg_has_log_file(struct mpv_global *global);
|
2019-11-17 23:44:12 +00:00
|
|
|
void mp_msg_set_early_logging(struct mpv_global *global, bool enable);
|
2014-01-16 20:24:39 +00:00
|
|
|
|
2023-12-15 18:38:07 +00:00
|
|
|
void mp_msg_flush_status_line(struct mp_log *log, bool clear);
|
2020-05-25 18:37:37 +00:00
|
|
|
void mp_msg_set_term_title(struct mp_log *log, const char *title);
|
2015-01-01 19:37:49 +00:00
|
|
|
|
msg: add a mechanism to output messages to a ringbuffer
Until now, mp_msg output always went to the terminal. There was no way
to grab the stream of output messages. But this will be needed by
various future changes: Lua scripts, slave mode, client library...
This commit allows registering a ring buffer. A callback would be more
straight-forward, but since msg.c sits at the bottom of the lock
hierarchy (it's used by virtually everything), this would probably be a
nightmare. A ring buffer will be simpler and more predictable in the
long run.
We allocate new memory for each ringbuffer entry, which is probably a
bit expensive. We could try to be clever and somehow pack the data
directly into the buffer, but I felt like this wouldn't be worth the
complexity. You'd have to copy the data a bunch of times anyway. I'm
hoping that we can get away with using the ringbuffer mechanism for
low frequency important messages only (and not e.g. for high volume
debug messages), so the cost doesn't matter that much.
A ringbuffer has a simple, single log level. I considered allowing
--msglevel style per-prefix configuration for each ringbuffer, but
that would have been pretty complicated to implement, and wouldn't
have been that useful either.
2014-01-16 20:26:31 +00:00
|
|
|
struct mp_log_buffer_entry {
|
|
|
|
char *prefix;
|
|
|
|
int level;
|
|
|
|
char *text;
|
|
|
|
};
|
|
|
|
|
2015-06-20 19:40:47 +00:00
|
|
|
// Use --msg-level option for log level of this log buffer
|
|
|
|
#define MP_LOG_BUFFER_MSGL_TERM (MSGL_MAX + 1)
|
msg: make --log-file buffered through a thread
Until now --log-file performed a blocking write to the log file, which
made any calling thread block for I/O. It even explicitly flushed after
every line (to make it tail-able, or to ensure a hard crash wouldn't
lose any of the output). This wasn't so good, because it could cause
real playback problems, which made it infeasible to enable it by
default.
Try to buffer it through a ring buffer and a thread. There's no other
choice but to use a thread, since async I/O on files is generally a big
and unportable pain. (We very much prefer portable pain.) Fortunately,
there's already a ring buffer (mp_log_buffer, normally for the client
API logging hook). This still involves some pretty messy locking. Give
each mp_log_buffer its own lock to make this easier.
This still makes calling threads block if the log buffer is full (unlike
with client API log buffers, which just drop messages). I don't want log
messages to get lost for this purpose. This also made locking pretty
complicated (without it, mp_log_buffer wouldn't have needed its own
lock). Maybe I'll remove this blocking again when it turns out to be
nonsense.
(We could avoid wasting an entire thread by "reusing" some other thread.
E.g. pick some otherwise not real time thread, and make it react to the
log buffer's wakeup callback. But let's not. It's complicated to abuse
random threads for this. It'd also raise locking complexity, because we
still want it to block on a full buffer.)
2020-01-29 22:34:59 +00:00
|
|
|
// For --log-file; --msg-level, but at least MSGL_DEBUG
|
|
|
|
#define MP_LOG_BUFFER_MSGL_LOGFILE (MSGL_MAX + 2)
|
2015-06-20 19:40:47 +00:00
|
|
|
|
msg: add a mechanism to output messages to a ringbuffer
Until now, mp_msg output always went to the terminal. There was no way
to grab the stream of output messages. But this will be needed by
various future changes: Lua scripts, slave mode, client library...
This commit allows registering a ring buffer. A callback would be more
straight-forward, but since msg.c sits at the bottom of the lock
hierarchy (it's used by virtually everything), this would probably be a
nightmare. A ring buffer will be simpler and more predictable in the
long run.
We allocate new memory for each ringbuffer entry, which is probably a
bit expensive. We could try to be clever and somehow pack the data
directly into the buffer, but I felt like this wouldn't be worth the
complexity. You'd have to copy the data a bunch of times anyway. I'm
hoping that we can get away with using the ringbuffer mechanism for
low frequency important messages only (and not e.g. for high volume
debug messages), so the cost doesn't matter that much.
A ringbuffer has a simple, single log level. I considered allowing
--msglevel style per-prefix configuration for each ringbuffer, but
that would have been pretty complicated to implement, and wouldn't
have been that useful either.
2014-01-16 20:26:31 +00:00
|
|
|
struct mp_log_buffer;
|
|
|
|
struct mp_log_buffer *mp_msg_log_buffer_new(struct mpv_global *global,
|
2014-06-06 17:24:30 +00:00
|
|
|
int size, int level,
|
|
|
|
void (*wakeup_cb)(void *ctx),
|
|
|
|
void *wakeup_cb_ctx);
|
msg: add a mechanism to output messages to a ringbuffer
Until now, mp_msg output always went to the terminal. There was no way
to grab the stream of output messages. But this will be needed by
various future changes: Lua scripts, slave mode, client library...
This commit allows registering a ring buffer. A callback would be more
straight-forward, but since msg.c sits at the bottom of the lock
hierarchy (it's used by virtually everything), this would probably be a
nightmare. A ring buffer will be simpler and more predictable in the
long run.
We allocate new memory for each ringbuffer entry, which is probably a
bit expensive. We could try to be clever and somehow pack the data
directly into the buffer, but I felt like this wouldn't be worth the
complexity. You'd have to copy the data a bunch of times anyway. I'm
hoping that we can get away with using the ringbuffer mechanism for
low frequency important messages only (and not e.g. for high volume
debug messages), so the cost doesn't matter that much.
A ringbuffer has a simple, single log level. I considered allowing
--msglevel style per-prefix configuration for each ringbuffer, but
that would have been pretty complicated to implement, and wouldn't
have been that useful either.
2014-01-16 20:26:31 +00:00
|
|
|
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);
|
2019-11-17 23:44:12 +00:00
|
|
|
void mp_msg_log_buffer_set_silent(struct mp_log_buffer *buffer, bool silent);
|
msg: add a mechanism to output messages to a ringbuffer
Until now, mp_msg output always went to the terminal. There was no way
to grab the stream of output messages. But this will be needed by
various future changes: Lua scripts, slave mode, client library...
This commit allows registering a ring buffer. A callback would be more
straight-forward, but since msg.c sits at the bottom of the lock
hierarchy (it's used by virtually everything), this would probably be a
nightmare. A ring buffer will be simpler and more predictable in the
long run.
We allocate new memory for each ringbuffer entry, which is probably a
bit expensive. We could try to be clever and somehow pack the data
directly into the buffer, but I felt like this wouldn't be worth the
complexity. You'd have to copy the data a bunch of times anyway. I'm
hoping that we can get away with using the ringbuffer mechanism for
low frequency important messages only (and not e.g. for high volume
debug messages), so the cost doesn't matter that much.
A ringbuffer has a simple, single log level. I considered allowing
--msglevel style per-prefix configuration for each ringbuffer, but
that would have been pretty complicated to implement, and wouldn't
have been that useful either.
2014-01-16 20:26:31 +00:00
|
|
|
|
2015-02-06 15:48:52 +00:00
|
|
|
int mp_msg_find_level(const char *s);
|
2014-01-16 20:24:39 +00:00
|
|
|
|
2014-10-10 11:44:08 +00:00
|
|
|
extern const char *const mp_log_levels[MSGL_MAX + 1];
|
2014-10-09 19:51:10 +00:00
|
|
|
extern const int mp_mpv_log_levels[MSGL_MAX + 1];
|
2014-01-16 20:34:47 +00:00
|
|
|
|
2014-01-16 20:24:39 +00:00
|
|
|
#endif
|