summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-12-20 21:07:10 +0100
committerwm4 <wm4@nowhere>2013-12-20 21:07:58 +0100
commite9e68fc399ed2805b43dff8f355142804e55c38c (patch)
tree5a4b3f08fe9c189eb51e0dab3ece4835ecd93b9e
parent6a8fc3f5e38f93c36d18ad8407d4f3f345d893db (diff)
downloadmpv-e9e68fc399ed2805b43dff8f355142804e55c38c.tar.bz2
mpv-e9e68fc399ed2805b43dff8f355142804e55c38c.tar.xz
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).
-rw-r--r--common/msg.c11
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);
fflush(stream);
+
+ pthread_mutex_unlock(&mp_msg_lock);
}
void mp_msg_va(int mod, int lev, const char *format, va_list va)