|
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.
|
A generic container abstraction based on OCC (Optimistic Concurrency Control). More...
#include "jh/detail/shared_ptr_atomic_shim.h"#include <memory>#include <atomic>#include <concepts>#include <cstdint>#include <functional>#include <type_traits>#include <optional>Go to the source code of this file.
Classes | |
| class | jh::conc::occ_box< T > |
| Generic container providing Optimistic Concurrency Control (OCC). More... | |
Namespaces | |
| namespace | jh::conc |
| Aggregated namespace for concurrency-aware resource containers. | |
Macros | |
| #define | JH_OCC_ENABLE_MULTI_COMMIT 1 |
Enable transactional multi-commit support for occ_box. | |
Functions | |
| template<typename... Boxes, typename... Funcs> | |
| bool | jh::conc::apply_to (std::tuple< Boxes &... > boxes, std::tuple< Funcs... > &&funcs) |
Apply functions to multiple occ_boxes atomically. | |
A generic container abstraction based on OCC (Optimistic Concurrency Control).
LBCC (Lock-Based Concurrency Control)
Built-in support in C++ (std::mutex, std::shared_mutex).
Flexible, efficient, but requires careful lock ordering to avoid deadlocks.
No wrapper provided in this library.
MVCC (Multi-Version Concurrency Control)
Used in databases for snapshot isolation.
Requires version chains, garbage collection, and complex rules.
Not suitable for lightweight, in-memory concurrency here.
occ_box<T>.A single read() operation typically incurs:
shared_ptr<state> (before/after validation). JH_OCC_ENABLE_MULTI_COMMIT == 1), one extra atomic load of flag_ is performed during validation. Reads are wait-free, never block writes, and retries only if a concurrent commit changes the state pointer between the two loads.
write() always creates a fresh copy of the object, applies the user lambda, and commits with a single CAS. write_ptr() allows the caller to supply a new shared_ptr<T>, avoiding deep copy overhead for large or expensive-to-copy objects. try_*() methods perform the first attempt outside of the loop. retries == 1 executes exactly once with no loop overhead. retries == 0 is equivalent to 1 (a single attempt). retries > 1, the loop covers the remaining retries - 1 attempts. std::optional allocation or an extra invoke in the retry path, both undesirable in hot loops. examples/example_occ_box.cpp for a full example. In short: the lambda can take a duration&, sleep if nonzero, update it (0 → min → min×base ... capped at max), then run business logic. JH_OCC_ENABLE_MULTI_COMMIT == 1 (default), contention is resolved by strict priority: multi-write > single-write > read. JH_OCC_ENABLE_MULTI_COMMIT is 1 (default): occ_box supports apply_to() for atomic multi-box transactions. flag_ (atomic<bool>) used as a transaction marker. read() incurs one additional atomic load to check flag_. JH_OCC_ENABLE_MULTI_COMMIT is 0: apply_to() is disabled. occ_box does not contain flag_, reducing object size. read() cost. 1.4.x
2025
| #define JH_OCC_ENABLE_MULTI_COMMIT 1 |
Enable transactional multi-commit support for occ_box.
Default: 1 (enabled)
If not defined manually, it defaults to:
#define JH_OCC_ENABLE_MULTI_COMMIT 1
If overriding manually in source code, it must be defined before any inclusion of the library public header (i.e. <jh/concurrency>) within the translation unit.
Configuration methods:
#define JH_OCC_ENABLE_MULTI_COMMIT 0
target_compile_definitions(target PRIVATE JH_OCC_ENABLE_MULTI_COMMIT=0)
-DJH_OCC_ENABLE_MULTI_COMMIT=0
When set to 1:
apply_to() transactional operations. occ_box instances to commit atomically as a single transaction (multi-commit). When set to 0:
apply_to() is not compiled.