From 9970075fa1754dd0244fc475420e8610aea65a82 Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Tue, 10 Oct 2017 11:47:35 +0800 Subject: [PATCH] fiber_mutex: fixed one bug when thread_safe parameter is set true --- lib_fiber/c/Makefile | 2 +- lib_fiber/changes.txt | 6 ++++ lib_fiber/cpp/include/fiber/fiber_lock.hpp | 4 +-- lib_fiber/cpp/src/fiber_lock.cpp | 34 ++++++++++++++++------ lib_fiber/samples/thread_lock/main.cpp | 4 +-- packaging/acl-libs.spec | 5 +++- 6 files changed, 40 insertions(+), 15 deletions(-) diff --git a/lib_fiber/c/Makefile b/lib_fiber/c/Makefile index fb61d1b42..44e2911ac 100644 --- a/lib_fiber/c/Makefile +++ b/lib_fiber/c/Makefile @@ -21,7 +21,7 @@ CFLAGS = -c -g -W \ -D_USE_FAST_MACRO \ -Wno-long-long \ -DUSE_JMP \ --DUSE_VALGRIND +#-DUSE_VALGRIND #-Wno-clobbered #-O3 diff --git a/lib_fiber/changes.txt b/lib_fiber/changes.txt index 3ed6305b4..38817d836 100644 --- a/lib_fiber/changes.txt +++ b/lib_fiber/changes.txt @@ -1,4 +1,10 @@ +67) 2017.10.10 +67.1) bugfix: fiber_mutex 当启用线程安全方式时,IO 操作过程会产生非法内存访问 +问题而导致事件进入死循环,原因是多个线程中的多个线程如果同时阻塞在同一 fd 上 +时会容易产生此问题,现修改为当进入 IO 读时,dup 出一个新的 fd 并使线程中的协程 +阻塞在该 fd 上 + 66) 2017.9.29 66.1) feature: fiber_mutex 可以同时支持线程锁和协程锁 diff --git a/lib_fiber/cpp/include/fiber/fiber_lock.hpp b/lib_fiber/cpp/include/fiber/fiber_lock.hpp index 0859521aa..d71a8d7e0 100644 --- a/lib_fiber/cpp/include/fiber/fiber_lock.hpp +++ b/lib_fiber/cpp/include/fiber/fiber_lock.hpp @@ -11,7 +11,7 @@ class fiber_mutex { public: fiber_mutex(bool thread_safe = false, unsigned int delay = 1000, - bool use_atomic_lock = false); + bool use_atomic_lock = true); ~fiber_mutex(void); bool lock(void); @@ -29,7 +29,7 @@ private: int out_; int in_; - bool lock_wait(void); + bool lock_wait(int in); }; class fiber_rwlock diff --git a/lib_fiber/cpp/src/fiber_lock.cpp b/lib_fiber/cpp/src/fiber_lock.cpp index 2a8f28992..ed6ab1403 100644 --- a/lib_fiber/cpp/src/fiber_lock.cpp +++ b/lib_fiber/cpp/src/fiber_lock.cpp @@ -7,6 +7,9 @@ # define USE_PIPE #endif +//#undef USE_EVENT +//#undef USE_PIPE + #include "acl_cpp/stdlib/thread.hpp" #include "acl_cpp/stdlib/thread_mutex.hpp" #include "acl_cpp/stdlib/log.hpp" @@ -20,7 +23,7 @@ namespace acl { fiber_mutex::fiber_mutex(bool thread_safe /* = false */, - unsigned int delay /* = 1000 */, bool use_atomic_lock /* = false */) + unsigned int delay /* = 1000 */, bool use_atomic_lock /* = true */) : delay_(delay) , waiters_(0) , readers_(0) @@ -91,15 +94,15 @@ fiber_mutex::~fiber_mutex(void) close(out_); } -bool fiber_mutex::lock_wait(void) +bool fiber_mutex::lock_wait(int in) { - if (in_ < 0) + if (in < 0) { (void) fiber::delay(delay_); return true; } - if (acl_read_poll_wait(in_, delay_) == -1) + if (acl_read_poll_wait(in, delay_) == -1) { if (errno == ACL_ETIMEDOUT) return true; @@ -115,7 +118,7 @@ bool fiber_mutex::lock_wait(void) written_--; long long n; - if (read(in_, &n, sizeof(n)) <= 0) + if (read(in, &n, sizeof(n)) <= 0) logger_error("thread-%lu, read error %s", acl::thread::thread_self(), last_serror()); @@ -135,8 +138,15 @@ bool fiber_mutex::lock(void) while (atomic_lock_->cas(0, 1) == 1) { - if (lock_wait() == false) + int in = in_ >= 0 ? dup(in_) : -1; + if (lock_wait(in) == false) + { + if (in >= 0) + close(in); return false; + } + if (in >= 0) + close(in); } } else if (thread_lock_) @@ -145,8 +155,15 @@ bool fiber_mutex::lock(void) while (thread_lock_->try_lock() == false) { - if (lock_wait() == false) + int in = in_ >= 0 ? dup(in_) : -1; + if (lock_wait(in) == false) + { + if (in >= 0) + close(in); return false; + } + if (in >= 0) + close(in); } } @@ -185,8 +202,6 @@ bool fiber_mutex::trylock(void) bool fiber_mutex::unlock(void) { - static const long long n = 100; - if (fiber::scheduled()) { __nfibers--; @@ -216,6 +231,7 @@ bool fiber_mutex::unlock(void) written_++; + static const long long n = 100; if (write(out_, &n, sizeof(n)) <= 0) logger_warn("write error=%s", last_serror()); diff --git a/lib_fiber/samples/thread_lock/main.cpp b/lib_fiber/samples/thread_lock/main.cpp index ae23c467c..40469dd5a 100644 --- a/lib_fiber/samples/thread_lock/main.cpp +++ b/lib_fiber/samples/thread_lock/main.cpp @@ -156,8 +156,8 @@ int main(int argc, char *argv[]) } } - - acl::fiber_mutex lock(true, read_wait, use_thread_mutex); + printf("use_thread_mutex: %s\r\n", use_thread_mutex ? "yes" : "no"); + acl::fiber_mutex lock(true, read_wait, use_thread_mutex ? false : true); std::vector threads; for (int i = 0; i < __nthreads; i++) diff --git a/packaging/acl-libs.spec b/packaging/acl-libs.spec index 7cd4045c0..c10d09dcc 100644 --- a/packaging/acl-libs.spec +++ b/packaging/acl-libs.spec @@ -1,7 +1,7 @@ Summary: The powerful c/c++ library and server framework Name: acl-libs Version: 3.3.0 -Release: 28 +Release: 29 Group: System/Libs License: IBM URL: http://cdnlog-web.qiyi.domain @@ -76,6 +76,9 @@ fi /etc/init.d/master %changelog +* Sat Oct 10 2018 zhengshuxin@qiyi.com 3.3.0-29-20171010.11 +- fiber_mutex: fixed one bug when thread_safe is true + * Sat Oct 07 2018 zhengshuxin@qiyi.com 3.3.0-28-20171007.23 - add event_mutex in lib_acl_cpp