Skip to content

Commit

Permalink
iox-eclipse-iceoryx#2301 Ensure SpinLock is inter-process safe
Browse files Browse the repository at this point in the history
  • Loading branch information
elBoberido committed Sep 21, 2024
1 parent d3182ac commit bbc5f04
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 3 deletions.
2 changes: 2 additions & 0 deletions iceoryx_hoofs/concurrent/sync/include/iox/spin_lock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -63,6 +64,7 @@ class SpinLock : public LockInterface<SpinLock>
concurrent::AtomicFlag m_lock_flag =
ATOMIC_FLAG_INIT; // NOTE: only initialization via assignment is guaranteed to work
const concurrent::Atomic<bool> m_recursive{false};
concurrent::Atomic<pid_t> m_pid{0};
concurrent::Atomic<uint64_t> m_recursive_count{0};
concurrent::Atomic<std::thread::id> m_tid{};
};
Expand Down
12 changes: 9 additions & 3 deletions iceoryx_hoofs/concurrent/sync/source/spin_lock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ SpinLock::SpinLock(const LockBehavior lock_behavior) noexcept

expected<void, LockError> 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))
{
Expand All @@ -58,6 +59,7 @@ expected<void, LockError> 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);

Expand All @@ -66,9 +68,10 @@ expected<void, LockError> SpinLock::lock_impl() noexcept

expected<void, UnlockError> 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);
}
Expand All @@ -81,6 +84,7 @@ expected<void, UnlockError> 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);
}
Expand All @@ -90,9 +94,10 @@ expected<void, UnlockError> SpinLock::unlock_impl() noexcept

expected<TryLock, TryLockError> 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))
{
Expand All @@ -105,6 +110,7 @@ expected<TryLock, TryLockError> 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);

Expand Down

0 comments on commit bbc5f04

Please sign in to comment.