From aba35f0494f3c2dc3849c450e3c76a7f85d0a7de Mon Sep 17 00:00:00 2001 From: JIANWEI WU Date: Fri, 9 Nov 2018 13:24:59 -0700 Subject: [PATCH 1/2] Changed to use posix robust mutex to allow subsequent mutex lock can grab the lock from previous dead owner to void deadlock. And it also fixed the issue #65. --- .../sync/posix/pthread_helpers.hpp | 5 +++-- .../sync/posix/recursive_mutex.hpp | 19 +++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/include/boost/interprocess/sync/posix/pthread_helpers.hpp b/include/boost/interprocess/sync/posix/pthread_helpers.hpp index c615c851e..818fc642e 100644 --- a/include/boost/interprocess/sync/posix/pthread_helpers.hpp +++ b/include/boost/interprocess/sync/posix/pthread_helpers.hpp @@ -41,8 +41,9 @@ namespace ipcdetail{ if(pthread_mutexattr_init(&m_attr)!=0 || pthread_mutexattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0 || (recursive && - pthread_mutexattr_settype(&m_attr, PTHREAD_MUTEX_RECURSIVE)!= 0 )) - throw interprocess_exception("pthread_mutexattr_xxxx failed"); + pthread_mutexattr_settype(&m_attr, PTHREAD_MUTEX_RECURSIVE) != 0 ) || + pthread_mutexattr_setrobust(&m_attr, PTHREAD_MUTEX_ROBUST) != 0 ) + throw interprocess_exception("pthread_mutexattr_xxxx failed"); } //!Destructor diff --git a/include/boost/interprocess/sync/posix/recursive_mutex.hpp b/include/boost/interprocess/sync/posix/recursive_mutex.hpp index 9ef4f1278..e1b924a90 100644 --- a/include/boost/interprocess/sync/posix/recursive_mutex.hpp +++ b/include/boost/interprocess/sync/posix/recursive_mutex.hpp @@ -87,16 +87,21 @@ inline posix_recursive_mutex::~posix_recursive_mutex() inline void posix_recursive_mutex::lock() { - if (pthread_mutex_lock(&m_mut) != 0) + int res = pthread_mutex_lock(&m_mut); + if (res == EOWNERDEAD) + pthread_mutex_consistent(&m_mut); + else if (res != 0) throw lock_exception(); } inline bool posix_recursive_mutex::try_lock() { int res = pthread_mutex_trylock(&m_mut); - if (!(res == 0 || res == EBUSY)) + if (res == EOWNERDEAD) + pthread_mutex_consistent(&m_mut); + else if (!(res == 0 || res == EBUSY)) throw lock_exception(); - return res == 0; + return (res == 0 || res == EOWNERDEAD); } inline bool posix_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time) @@ -110,9 +115,11 @@ inline bool posix_recursive_mutex::timed_lock(const boost::posix_time::ptime &ab timespec ts = ptime_to_timespec(abs_time); int res = pthread_mutex_timedlock(&m_mut, &ts); - if (res != 0 && res != ETIMEDOUT) - throw lock_exception(); - return res == 0; + if (res == EOWNERDEAD) + pthread_mutex_consistent(&m_mut); + else if (res != 0 && res != ETIMEDOUT) + throw lock_exception(); + return (res == 0 || res == EOWNERDEAD); #else //BOOST_INTERPROCESS_POSIX_TIMEOUTS From 34fc89a1c33852d767d9aa4dd1c72918e42cc569 Mon Sep 17 00:00:00 2001 From: JIANWEI WU Date: Tue, 18 Dec 2018 10:42:23 -0700 Subject: [PATCH 2/2] throw a owner dead exception when previous owner has been dead, but still keep the mutex locked with new owner --- .../sync/posix/recursive_mutex.hpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/include/boost/interprocess/sync/posix/recursive_mutex.hpp b/include/boost/interprocess/sync/posix/recursive_mutex.hpp index e1b924a90..5e824cb6b 100644 --- a/include/boost/interprocess/sync/posix/recursive_mutex.hpp +++ b/include/boost/interprocess/sync/posix/recursive_mutex.hpp @@ -89,7 +89,10 @@ inline void posix_recursive_mutex::lock() { int res = pthread_mutex_lock(&m_mut); if (res == EOWNERDEAD) - pthread_mutex_consistent(&m_mut); + { + pthread_mutex_consistent(&m_mut); + throw interprocess_exception(owner_dead_error); + } else if (res != 0) throw lock_exception(); } @@ -98,10 +101,13 @@ inline bool posix_recursive_mutex::try_lock() { int res = pthread_mutex_trylock(&m_mut); if (res == EOWNERDEAD) - pthread_mutex_consistent(&m_mut); + { + pthread_mutex_consistent(&m_mut); + throw interprocess_exception(owner_dead_error); + } else if (!(res == 0 || res == EBUSY)) throw lock_exception(); - return (res == 0 || res == EOWNERDEAD); + return (res == 0); } inline bool posix_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time) @@ -116,10 +122,13 @@ inline bool posix_recursive_mutex::timed_lock(const boost::posix_time::ptime &ab timespec ts = ptime_to_timespec(abs_time); int res = pthread_mutex_timedlock(&m_mut, &ts); if (res == EOWNERDEAD) - pthread_mutex_consistent(&m_mut); + { + pthread_mutex_consistent(&m_mut); + throw interprocess_exception(owner_dead_error); + } else if (res != 0 && res != ETIMEDOUT) throw lock_exception(); - return (res == 0 || res == EOWNERDEAD); + return (res == 0); #else //BOOST_INTERPROCESS_POSIX_TIMEOUTS