aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2022-06-03 11:05:17 +0200
committerbfredl <bjorn.linse@gmail.com>2022-06-03 11:08:32 +0200
commit640c695a7b9e692f9e689782e91f95f326061fbe (patch)
tree83ba5ef7d4321460344d6ec0c985831732866249 /src
parent9745941ef620da86bf18f965f85e8fc2ce8206b5 (diff)
downloadrneovim-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.c21
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();