From ebe502a747756f553a5b240cd8fce5b1714b733b Mon Sep 17 00:00:00 2001 From: Ratchanan Srirattanamet Date: Sun, 20 Feb 2022 09:58:03 +0000 Subject: [PATCH] db: fix dead lock in zmDbQueue::stop() Notifying `mCondition` without taking the lock causes a race condition in ::process() between checking `mTerminate` and waiting for the `mCondition`, which causes a dead lock. This commit moves writing to `mTerminate` and notifying `mCondition` under the lock to eliminate race condition and dead lock. This is not theoretical. It has caused zmu to hang at exit on a Raspberry Pi 4, exhuasting PHP-FPM process pool. The stacks below are captured when running ZoneMinder 1.36.12-focal1 on Ubuntu 20.04: (gdb) thread apply all bt Thread 2 (Thread 0xffff80c1c880 (LWP 259988)): #0 futex_wait_cancelable (private=0, expected=0, futex_word=0xaaaae0584e80 ) at ../sysdeps/nptl/futex-internal.h:183 #1 __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0xaaaae0584e28 , cond=0xaaaae0584e58 ) at pthread_cond_wait.c:508 #2 __pthread_cond_wait (cond=0xaaaae0584e58 , mutex=0xaaaae0584e28 ) at pthread_cond_wait.c:638 #3 0x0000ffff8700d670 in std::condition_variable::wait(std::unique_lock&) () from /lib/aarch64-linux-gnu/libstdc++.so.6 #4 0x0000aaaae0438f08 in zmDbQueue::process (this=0xaaaae0584dd0 ) at ./src/zm_db.cpp:250 #5 0x0000ffff87013fac in ?? () from /lib/aarch64-linux-gnu/libstdc++.so.6 #6 0x0000ffff891264fc in start_thread (arg=0xffffe60d84bf) at pthread_create.c:477 #7 0x0000ffff86dd767c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/clone.S:78 Thread 1 (Thread 0xffff80c23010 (LWP 259987)): #0 __pthread_clockjoin_ex (threadid=281472841926784, thread_return=0x0, clockid=0, abstime=, block=) at pthread_join_common.c:145 #1 0x0000ffff87014240 in std::thread::join() () from /lib/aarch64-linux-gnu/libstdc++.so.6 #2 0x0000aaaae04314d0 in exit_zmu (exit_code=0) at ./src/zmu.cpp:200 #3 0x0000aaaae042f4c8 in main (argc=, argv=) at ./src/zmu.cpp:797 --- src/zm_db.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/zm_db.cpp b/src/zm_db.cpp index cc0797c12..76bd04e27 100644 --- a/src/zm_db.cpp +++ b/src/zm_db.cpp @@ -238,8 +238,13 @@ zmDbQueue::~zmDbQueue() { } void zmDbQueue::stop() { - mTerminate = true; - mCondition.notify_all(); + { + std::unique_lock lock(mMutex); + + mTerminate = true; + mCondition.notify_all(); + } + if (mThread.joinable()) mThread.join(); }