diff options
authorwm4 <wm4@nowhere>2013-12-20 21:07:10 +0100
committerwm4 <wm4@nowhere>2013-12-20 21:07:58 +0100
commite9e68fc399ed2805b43dff8f355142804e55c38c (patch)
parent6a8fc3f5e38f93c36d18ad8407d4f3f345d893db (diff)
msg: use a global lock to synchronize printing
We have certain race conditions coming from doing multiple fprintf() calls (setting up colors etc.). I'm not sure whether it would be worth changing to code such that we do only one fprintf() call (and assume this synchronizes access), but considering it would be hard to do (Windows compatibility, ...), and that stdio uses per FILE locks anyway, this is simpler and probably not less efficient. Also, there's no problem handling the weird statusline special case this way. Note that mp_msg_* calls which are silent won't acquire the lock, and acquiring the lock happens on actual output only (which is slow and serialized anyway).
1 files changed, 7 insertions, 4 deletions
diff --git a/common/msg.c b/common/msg.c
index 390794b4cd..6d4e374a24 100644
--- a/common/msg.c
+++ b/common/msg.c
@@ -147,13 +147,14 @@ static void set_msg_color(FILE* stream, int lev)
void mp_msg_log_va(struct mp_log *log, int lev, const char *format, va_list va)
- char tmp[MSGSIZE_MAX];
- FILE *stream =
- (mp_msg_stdout_in_use || (lev == MSGL_STATUS)) ? stderr : stdout;
if (!mp_msg_test_log(log, lev))
return; // do not display
+ pthread_mutex_lock(&mp_msg_lock);
+ FILE *stream = (mp_msg_stdout_in_use || lev == MSGL_STATUS) ? stderr : stdout;
+ char tmp[MSGSIZE_MAX];
vsnprintf(tmp, MSGSIZE_MAX, format, va);
tmp[MSGSIZE_MAX - 2] = '\n';
tmp[MSGSIZE_MAX - 1] = 0;
@@ -182,6 +183,8 @@ void mp_msg_log_va(struct mp_log *log, int lev, const char *format, va_list va)
if (mp_msg_docolor())
terminal_set_foreground_color(stream, -1);
+ pthread_mutex_unlock(&mp_msg_lock);
void mp_msg_va(int mod, int lev, const char *format, va_list va)