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
shared_process_mutex.h File Reference

Cross-process shared (read/write) timed mutex built from process primitives. More...

#include "jh/metax/t_str.h"
#include "jh/synchronous/ipc/process_mutex.h"
#include "jh/synchronous/ipc/process_counter.h"
#include "jh/synchronous/ipc/process_cond_var.h"
#include "jh/synchronous/ipc/ipc_limits.h"
#include <chrono>
#include <stdexcept>
#include <iostream>
#include <thread>

Go to the source code of this file.

Classes

class  jh::sync::ipc::shared_process_mutex< S, HighPriv >
 Cross-process shared/exclusive timed mutex with optional upgrade support. More...

Namespaces

namespace  jh::sync
 Aggregated entry point for synchronization and coordination facilities.
namespace  jh::sync::ipc
 Synchronous inter-process coordination primitives.

Variables

template<jh::meta::TStr S, bool HighPriv>
bool jh::sync::ipc::shared_process_mutex< S, HighPriv >::has_shared_lock_ = false
template<jh::meta::TStr S, bool HighPriv>
bool jh::sync::ipc::shared_process_mutex< S, HighPriv >::has_exclusive_lock_ = false
template<jh::meta::TStr S, bool HighPriv>
bool jh::sync::ipc::shared_process_mutex< S, HighPriv >::has_prior_lock_ = false

Detailed Description

Cross-process shared (read/write) timed mutex built from process primitives.

Overview

jh::sync::ipc::shared_process_mutex is a fully process-visible synchronization primitive providing both shared and exclusive locking semantics, similar to std::shared_timed_mutex, but implemented entirely from process-named OS primitives. It enables multiple participants — threads, coroutines, or processes — to coordinate access to a shared resource without requiring shared memory.

Component composition

  • process_mutex<S + ".exc"> — exclusive access control, preventing new readers during write phases.
  • process_cond_var<S + ".cond"> — global condition variable used to wake writers or upgraders when readers exit.
  • process_counter<S + ".cnt"> — global atomic counter tracking the number of active readers system-wide.
  • process_mutex<S + ".pri"> — preemption mutex used exclusively by upgraders. It allows a participant upgrading from shared to exclusive mode to preempt all waiting writers and maintain upgrade continuity. Once .pri is held, no other process may enter exclusive mode until the upgrade completes. This lock does not enforce fairness — it ensures transactional upgrade atomicity.

Dependency

The implementation is composed of three fundamental process-level synchronization primitives:

  • #include "jh/synchronous/process_mutex.h" — built upon named semaphore.
  • #include "jh/synchronous/process_counter.h" — built upon shared memory.
  • #include "jh/synchronous/process_cond_var.h" — built upon shared memory.

Platform compatibility

On POSIX-compliant systems, all primitives are implemented using native named IPC mechanisms (POSIX semaphores and shared memory segments) and require no special privilege.

On Windows, due to the discrepancy between POSIX and Win32 IPC naming and visibility rules:

  • Semaphores must be created under the Local\ namespace to be visible within the same session (used by process_mutex).
  • Shared memory objects (process_counter and process_cond_var) must be created under the Global\ namespace to allow inter-process linkage.

Important note (Windows privilege requirement)

Because access to Global\ objects requires administrative rights on Windows, both process_counter and process_cond_var must be initialized under elevated privilege. Consequently, any component that depends on them — including shared_process_mutex — must be executed as an Administrator.

This restriction does not apply to POSIX systems.

Testing and validation

On Windows, we built the library under the URT64 toolchain and verified execution in the native PowerShell environment. The IPC primitives were confirmed to function correctly across processes in the same session.

Note that MSYS2 (URT64) environments typically run under root-equivalent privilege, meaning CI environments may fail to detect privilege-related issues.

As of the current implementation:

  • process_mutex (semaphore-based) — operates correctly under normal privilege.
  • process_counter and process_cond_var (shared-memory-based) — require administrator privilege for creation and access.

Consequently, shared_process_mutex on Windows functions correctly only when executed under administrative rights.

Design stance

In the jh-toolkit IPC model, Windows is treated as a second-class citizen: parity of semantics with POSIX is ensured, but the privilege requirement remains unavoidable. Therefore, when using shared_process_mutex for inter-process read/write coordination on Windows, administrative rights are mandatory.

Design guarantees

  • Global visibility: all cooperating processes and threads share the same OS-named primitives.
  • Compile-time fixed identity: the template parameter TStr S uniquely defines the synchronization group.
  • Exclusive upgrade continuity: once an upgrade begins, it completes without interference from writers.
  • Deterministic semantics: fairness is not guaranteed; consistency and isolation are prioritized.

Upgrade semantics

The upgrade operation may be initiated by any participant holding a shared lock — including threads, coroutines, or separate processes bound to the same named primitives. Because upgrade must occur in a continuous global scope, the upgrader cannot yield to a waiting writer without breaking its semantic integrity.

Therefore, if .exc cannot be immediately acquired, the upgrader seizes .pri to preempt all writers that were already waiting. Once .pri is held, the upgrader waits for all other readers to exit and then transitions into exclusive mode. Any concurrent upgrader attempting the same will be treated as a global protocol violation and cause forced unlink and termination.