JH-Toolkit v1.4.1
An engineering-oriented C++20 toolkit with duck-typed concepts, static design, async coroutines, and semantic containers — header-only, RTTI-free, and concurrency-friendly.
Loading...
Searching...
No Matches
jh::sync::ipc::shared_process_mutex< S, HighPriv > Class Template Reference

Cross-process shared/exclusive timed mutex with optional upgrade support. More...

#include <jh/synchronous/ipc/shared_process_mutex.h>

Public Member Functions

 shared_process_mutex (const shared_process_mutex &)=delete
shared_process_mutex & operator= (const shared_process_mutex &)=delete
void lock ()
 Acquire exclusive access (blocking).
bool try_lock ()
 Try to acquire exclusive access immediately.
template<typename Rep, typename Period>
bool try_lock_for (const std::chrono::duration< Rep, Period > &d)
 Attempt to acquire exclusive access for a limited duration.
template<typename Clock, typename Duration>
bool try_lock_until (const std::chrono::time_point< Clock, Duration > &tp)
 Attempt to acquire exclusive access until a specific time point.
void unlock ()
 Release exclusive access.
void lock_shared ()
 Acquire shared access.
bool try_lock_shared ()
 Attempt to acquire shared access immediately.
template<typename Rep, typename Period>
bool try_lock_shared_for (const std::chrono::duration< Rep, Period > &d)
 Attempt to acquire shared access for a limited duration.
template<typename Clock, typename Duration>
bool try_lock_shared_until (const std::chrono::time_point< Clock, Duration > &tp)
 Attempt to acquire shared access until a time point.
void unlock_shared ()
 Release shared access.
void upgrade_lock ()
 Upgrade from shared to exclusive mode (system-wide).
void upgrade_lock ()=delete
 Disabled for non-privileged variants.

Static Public Member Functions

static shared_process_mutex & instance ()
 Access the process-wide singleton instance of this mutex.
static void unlink ()
 Remove all associated process primitives.
static void unlink ()=delete
 Disabled for non-privileged variants.

Detailed Description

template<jh::meta::TStr S, bool HighPriv>
requires (limits::valid_object_name<S, limits::max_name_length - 8>())
class jh::sync::ipc::shared_process_mutex< S, HighPriv >

Cross-process shared/exclusive timed mutex with optional upgrade support.

Overview

jh::sync::ipc::shared_process_mutex is a process-visible synchronization primitive providing shared, exclusive, and (optionally) upgradeable locking semantics, similar to std::shared_timed_mutex but implemented from process-level IPC primitives.

Composition

Behavior

  • Implements all std::shared_timed_mutex interfaces (lock, try_lock*, lock_shared, try_lock_shared*).
  • The HighPriv variant adds upgrade_lock() and unlink().
  • Thread- and coroutine-local reentrancy is supported; repeated calls to lock() or lock_shared() in the same execution context are idempotent.
  • Lock ownership is tracked via thread_local flags; release operations are similarly idempotent within the same participant.

Upgrade semantics

  • Upgrade is continuous and exclusive: once started, it cannot yield or be interrupted.
  • Only one upgrader may exist system-wide. Concurrent upgrades are undefined behavior (UB).
  • During upgrade, the participant seizes .pri to preempt writers and preserve transactional consistency.
  • If two participants may attempt upgrade, it is recommended to protect the upgrade path with an additional mutex and use try_lock() to ensure a single active upgrader.

Design notes

  • This class models the behavior of std::shared_timed_mutex, but is implemented from process-wide IPC primitives.
  • It is an engineering-level primitive: deterministic, portable, and designed for correctness rather than fairness.
  • Within a single thread or coroutine context, (a coroutine and the thread it is executing on, that is, the first thread to attempt to resume it, are considered the same participant), all lock operations are idempotent. Repeated acquisitions or releases are safe and treated as no-ops. This enables reentrant patterns for coroutine and task frameworks.
  • Across threads or processes, reentrancy is not propagated — holding a lock in one thread does not imply ownership in another.
  • notify_one() is used intentionally: only writers wait on the condition variable, and at most one writer should proceed when readers complete.
  • Fully compatible with RAII wrappers (std::shared_lock, std::unique_lock, std::lock_guard).

Privilege and cleanup

  • Normal variant (HighPriv == false): shared/exclusive locks only.
  • High-privileged variant (HighPriv == true): adds upgrade support and unlink().
  • Unlink removes all associated IPC objects: .exc, .cond, .cnt, and .pri.

Member Function Documentation

◆ instance()

template<jh::meta::TStr S, bool HighPriv>
shared_process_mutex & jh::sync::ipc::shared_process_mutex< S, HighPriv >::instance ( )
inlinestatic

Access the process-wide singleton instance of this mutex.

Returns
A reference to the global synchronization object.

◆ lock()

template<jh::meta::TStr S, bool HighPriv>
void jh::sync::ipc::shared_process_mutex< S, HighPriv >::lock ( )
inline

Acquire exclusive access (blocking).

Sequence:

  1. Acquire .exc to block new readers.
  2. Wait until readers_ == 0.
  3. Acquire .pri to ensure no upgrader interferes.

The participant then has full exclusive access across all processes.

◆ lock_shared()

template<jh::meta::TStr S, bool HighPriv>
void jh::sync::ipc::shared_process_mutex< S, HighPriv >::lock_shared ( )
inline

Acquire shared access.

Locks .exc briefly to safely increment readers_, ensuring no writer is entering concurrently.

◆ try_lock()

template<jh::meta::TStr S, bool HighPriv>
bool jh::sync::ipc::shared_process_mutex< S, HighPriv >::try_lock ( )
inline

Try to acquire exclusive access immediately.

Returns
true if successful, false otherwise.

◆ unlink()

template<jh::meta::TStr S, bool HighPriv>
void jh::sync::ipc::shared_process_mutex< S, HighPriv >::unlink ( )
inlinestatic

Remove all associated process primitives.

Removes the following objects from the OS namespace:

◆ unlock()

template<jh::meta::TStr S, bool HighPriv>
void jh::sync::ipc::shared_process_mutex< S, HighPriv >::unlock ( )
inline

Release exclusive access.

Steps:

  1. Release .pri.
  2. Signal .cond to wake blocked writers or upgraders.
  3. If the lock was not obtained via upgrade preemption, release .exc.

◆ unlock_shared()

template<jh::meta::TStr S, bool HighPriv>
void jh::sync::ipc::shared_process_mutex< S, HighPriv >::unlock_shared ( )
inline

Release shared access.

Decrements readers_; if this was the last reader (old == 1), signals .cond to wake one waiting writer or upgrader.

◆ upgrade_lock()

template<jh::meta::TStr S, bool HighPriv>
void jh::sync::ipc::shared_process_mutex< S, HighPriv >::upgrade_lock ( )
inline

Upgrade from shared to exclusive mode (system-wide).

Steps:

  1. Requires the participant to hold a shared lock.
  2. Attempts to acquire .exc (blocks new readers).
  3. If .exc is held by another writer, acquires .pri to preempt that writer and maintain upgrade continuity.
  4. If .pri cannot be acquired, another upgrader is active — treated as fatal violation.
  5. Waits until all other readers exit (readers_ == 1).
  6. Decrements its reader count and transitions into exclusive mode.

This operation preserves global upgrade atomicity and ensures consistency across processes.


The documentation for this class was generated from the following file: