From bbc5f042d31646a1a94d63bb548fc9659acc0220 Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Sat, 21 Sep 2024 19:04:31 +0200 Subject: [PATCH] iox-#2301 Ensure SpinLock is inter-process safe --- .../concurrent/sync/include/iox/spin_lock.hpp | 2 ++ iceoryx_hoofs/concurrent/sync/source/spin_lock.cpp | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/iceoryx_hoofs/concurrent/sync/include/iox/spin_lock.hpp b/iceoryx_hoofs/concurrent/sync/include/iox/spin_lock.hpp index 4958cfeefd..32c66d4f67 100644 --- a/iceoryx_hoofs/concurrent/sync/include/iox/spin_lock.hpp +++ b/iceoryx_hoofs/concurrent/sync/include/iox/spin_lock.hpp @@ -17,6 +17,7 @@ #ifndef IOX_HOOFS_CONCURRENT_SYNC_SPIN_LOCK_HPP #define IOX_HOOFS_CONCURRENT_SYNC_SPIN_LOCK_HPP +#include "iceoryx_platform/unistd.hpp" #include "iox/atomic.hpp" #include "iox/lock_interface.hpp" @@ -63,6 +64,7 @@ class SpinLock : public LockInterface concurrent::AtomicFlag m_lock_flag = ATOMIC_FLAG_INIT; // NOTE: only initialization via assignment is guaranteed to work const concurrent::Atomic m_recursive{false}; + concurrent::Atomic m_pid{0}; concurrent::Atomic m_recursive_count{0}; concurrent::Atomic m_tid{}; }; diff --git a/iceoryx_hoofs/concurrent/sync/source/spin_lock.cpp b/iceoryx_hoofs/concurrent/sync/source/spin_lock.cpp index d42c4a217e..dfe8bb2172 100644 --- a/iceoryx_hoofs/concurrent/sync/source/spin_lock.cpp +++ b/iceoryx_hoofs/concurrent/sync/source/spin_lock.cpp @@ -41,9 +41,10 @@ SpinLock::SpinLock(const LockBehavior lock_behavior) noexcept expected SpinLock::lock_impl() noexcept { + auto pid = getpid(); auto tid = std::this_thread::get_id(); - if (m_tid.load() == tid) + if (m_pid.load() == pid && m_tid.load() == tid) { if (m_recursive.load(std::memory_order_relaxed)) { @@ -58,6 +59,7 @@ expected SpinLock::lock_impl() noexcept detail::adaptive_wait spinner; spinner.wait_loop([this] { return this->m_lock_flag.test_and_set(std::memory_order_acquire); }); + m_pid.store(pid); m_tid.store(tid); m_recursive_count.store(1); @@ -66,9 +68,10 @@ expected SpinLock::lock_impl() noexcept expected SpinLock::unlock_impl() noexcept { + auto pid = getpid(); auto tid = std::this_thread::get_id(); - if (m_tid.load() != tid) + if (m_pid.load() != pid || m_tid.load() != tid) { return err(UnlockError::NOT_OWNED_BY_THREAD); } @@ -81,6 +84,7 @@ expected SpinLock::unlock_impl() noexcept auto old_recursive_count = m_recursive_count.fetch_sub(1); if (old_recursive_count == 1) { + m_pid.store(0); m_tid.store(std::thread::id()); m_lock_flag.clear(std::memory_order_release); } @@ -90,9 +94,10 @@ expected SpinLock::unlock_impl() noexcept expected SpinLock::try_lock_impl() noexcept { + auto pid = getpid(); auto tid = std::this_thread::get_id(); - if (m_tid.load() == tid) + if (m_pid.load() == pid && m_tid.load() == tid) { if (m_recursive.load(std::memory_order_relaxed)) { @@ -105,6 +110,7 @@ expected SpinLock::try_lock_impl() noexcept if (!m_lock_flag.test_and_set(std::memory_order_acquire)) { + m_pid.store(pid); m_tid.store(tid); m_recursive_count.store(1);