diff options
author | bfredl <bjorn.linse@gmail.com> | 2022-06-03 11:05:17 +0200 |
---|---|---|
committer | bfredl <bjorn.linse@gmail.com> | 2022-06-03 11:08:32 +0200 |
commit | 640c695a7b9e692f9e689782e91f95f326061fbe (patch) | |
tree | 83ba5ef7d4321460344d6ec0c985831732866249 /src | |
parent | 9745941ef620da86bf18f965f85e8fc2ce8206b5 (diff) | |
download | rneovim-640c695a7b9e692f9e689782e91f95f326061fbe.tar.gz rneovim-640c695a7b9e692f9e689782e91f95f326061fbe.tar.bz2 rneovim-640c695a7b9e692f9e689782e91f95f326061fbe.zip |
fix(logging): make logmsg() thread-safe again
problem: data race when `recursive` is read outside of mutex by thread A
while thread B has taken the mutex and modifies it.
solution: use a recursive lock.
ref #18764
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/log.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/src/nvim/log.c b/src/nvim/log.c index c0a73a00fd..f12b844103 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -105,7 +105,7 @@ static bool log_path_init(void) void log_init(void) { - uv_mutex_init(&mutex); + uv_mutex_init_recursive(&mutex); // AFTER init_homedir ("~", XDG) and set_init_1 (env vars). 22b52dd462e5 #11501 log_path_init(); did_log_init = true; @@ -150,15 +150,6 @@ bool logmsg(int log_level, const char *context, const char *func_name, int line_ // set_init_1 may try logging before we are ready. 6f27f5ef91b3 #10183 return false; } - if (recursive) { - if (!did_msg) { - did_msg = true; - char *arg1 = func_name ? xstrdup(func_name) : (context ? xstrdup(context) : NULL); - multiqueue_put(main_loop.events, on_log_recursive_event, 2, arg1, line_num); - } - g_stats.log_skip++; - return false; - } if (log_level < MIN_LOG_LEVEL) { return false; @@ -171,6 +162,16 @@ bool logmsg(int log_level, const char *context, const char *func_name, int line_ #endif log_lock(); + if (recursive) { + if (!did_msg) { + did_msg = true; + char *arg1 = func_name ? xstrdup(func_name) : (context ? xstrdup(context) : NULL); + loop_schedule_deferred(&main_loop, event_create(on_log_recursive_event, 2, arg1, line_num)); + } + g_stats.log_skip++; + return false; + } + recursive = true; bool ret = false; FILE *log_file = open_log_file(); |