Lock-free shared memory primitives for real-time C++ and Python
Project description
safe-shm
Lock-free shared memory primitives for real-time C++ and Python.
Header-only C++23 library providing seqlock, cyclic ring buffer, time-series temporal queries, and lifecycle management — all over POSIX shared memory with zero-copy cross-process communication. Uses Linux futex for blocking waits, std::atomic_ref for lock-free access, and per-slot seqlocks to eliminate contention.
Works on x86_64 and ARM64 Linux.
Dependencies
shm— POSIX shared memory wrapperexception-rt— runtime exception utilitiesfmt— formattingnanobind(optional) — Python bindingsdoctest(test only) — fetched automaticallynanobench(bench only) — fetched automatically
Components
Core Primitives
| Header | Class | Description |
|---|---|---|
flat_type.hpp |
FlatType |
Concept: trivially_copyable && standard_layout |
seqlock.hpp |
SeqlockWriter<T>, SeqlockReader<T> |
Lock-free single-value read/write with torn-read detection |
cyclic_buffer.hpp |
CyclicBufferWriter<T,N>, CyclicBufferReader<T,N> |
Lock-free ring buffer with per-slot seqlock |
time_series.hpp |
TimeSeries<T,N> |
Temporal queries on cyclic buffer (closest, interpolation, freshness) |
stamped.hpp |
Stamped<T> |
Metadata envelope: {timestamp_ns, sequence, data} |
sanitized_key.hpp |
SanitizedKey<Tag> |
Strong-typed temporal key with external validator (opt-in) |
shm_lifecycle.hpp |
OwnedShm<T>, ShmHeader |
RAII ownership, heartbeat liveness, cleanup utilities |
Legacy / Specialized
| Header | Class | Description |
|---|---|---|
storage.hpp |
Storage<T> |
Write-side shared memory (futex-locked) |
dblbuf_loader.hpp |
DblBufLoader<T> |
Double-buffered async reader with background jthread |
image_shm.hpp |
DoubleBufferShm<T> |
Combined reader/writer with double buffering |
image.hpp |
Image<W,H,TYPE> |
Compile-time image types (FHD/4K, RGB/RGBA/NV12) |
shared_memory.hpp |
SharedMemory<T> |
Simple typed shm wrapper (no sync) |
producer_consumer.hpp |
ProducerConsumer<T> |
Semaphore-based producer/consumer |
shm_stats.hpp |
ShmStats |
Diagnostic counters with zero-cost opt-out via [[no_unique_address]] |
Architecture
Seqlock (single value, lock-free)
Writer Reader
┌────────────────────┐ ┌────────────────────┐
│ seq++ (odd) │ │ read seq (acquire) │
│ memcpy data │ /dev/shm/name │ memcpy data │
│ seq++ (even) ├────────────────►│ read seq (acquire) │
│ futex_wake │ │ if changed → retry │
└────────────────────┘ └────────────────────┘
CyclicBuffer (ring buffer, per-slot seqlock)
Writer Reader
┌──────────────────────┐ ┌──────────────────────────┐
│ idx = writes & (N-1) │ │ get_latest() │
│ slot[idx].seq++ (odd)│ /dev/shm/name │ get(reverse_index) │
│ memcpy slot[idx].data├─────────────────►│ try_get() → optional<T> │
│ slot[idx].seq++ (even│ │ wait_for_write() [futex] │
│ total_writes++ │ │ │
│ futex_wake │ │ TimeSeries layer: │
└──────────────────────┘ │ find_closest(key) │
│ find_interpolation_pair │
SHM layout: │ get_latest_if_fresh │
[total_writes] [slot₀] [slot₁] .. [slotₙ₋₁] │
Each slot: [seq_counter | T data] └──────────────────────────┘
Lifecycle Management
OwnedShm<T>
┌──────────────────────────────────┐
│ ShmHeader (32 bytes) │
│ magic: 0x53484D48 │
│ version, heartbeat_ns │
│ writer_pid │
├──────────────────────────────────┤
│ T data (user payload) │
└──────────────────────────────────┘
RAII: unlinks /dev/shm on destruction
is_writer_alive(): PID check + heartbeat
Choosing a Transport
| Need | Use | Latency |
|---|---|---|
| Single latest value, maximum speed | Seqlock<T> |
~140 ns (64 B) |
| Ring buffer history + temporal queries | CyclicBuffer<T,N> + TimeSeries |
~45 ns lookup |
| Double-buffered async loading (images) | DoubleBufferShm<T> |
~1 µs (FHD) |
| SHM with ownership tracking | OwnedShm<T> |
— |
| Simple typed shm (no sync) | SharedMemory<T> |
~1 ns |
Quick Start
Seqlock (cross-process, lock-free)
#include "safe-shm/seqlock.hpp"
// Writer process
safe_shm::SeqlockWriter<SensorData> writer("sensor_shm");
writer.store(SensorData{20.5, 1013.25, 45.0, now_ms()});
// Reader process
safe_shm::SeqlockReader<SensorData> reader("sensor_shm");
auto data = reader.load(); // non-blocking
auto data2 = reader.load_blocking(last_seq, timeout); // blocks until new data
CyclicBuffer + TimeSeries (ring buffer with temporal queries)
#include "safe-shm/cyclic_buffer.hpp"
#include "safe-shm/stamped.hpp"
#include "safe-shm/time_series.hpp"
using StampedIMU = safe_shm::Stamped<IMUReading>;
// Writer: insert stamped readings at 200 Hz
safe_shm::CyclicBufferWriter<StampedIMU, 64> writer("imu_shm");
writer.insert(safe_shm::stamp(imu_reading, seq++));
// Reader: temporal queries
safe_shm::TimeSeries<StampedIMU, 64> ts("imu_shm");
auto latest = ts.get_latest();
auto closest = ts.find_closest(target_ns); // binary search O(log N)
auto closest = ts.find_closest(target_ns, 100'000); // with max_distance guard
auto interp = ts.find_interpolation_pair(target_ns); // {before, after, alpha}
auto fresh = ts.get_latest_if_fresh(min_timestamp); // staleness check
Lifecycle Management
#include "safe-shm/shm_lifecycle.hpp"
// RAII-managed SHM segment with header
safe_shm::OwnedShm<Config> owned("my_config");
owned.data() = {1.5, 0.0, 3};
owned.update_heartbeat();
// Remote liveness check
if (safe_shm::is_writer_alive(header, /*max_stale_ns=*/1'000'000'000))
fmt::print("Writer is alive\n");
// Cleanup utilities
for (auto const& seg : safe_shm::shm_list("stale_"))
safe_shm::shm_remove(seg);
Python Bindings
import safe_shm_py as shm
# Seqlock
writer = shm.SeqlockWriterF64("my_shm")
writer.store(3.14159)
reader = shm.SeqlockReaderF64("my_shm")
value = reader.load() # 3.14159
# CyclicBuffer + TimeSeries
cb_writer = shm.CyclicBufferWriterStampedF64("ring_shm")
s = shm.StampedF64()
s.timestamp_ns = shm.monotonic_now_ns()
s.sequence = 0
s.data = 42.0
cb_writer.insert(s)
ts = shm.TimeSeriesStampedF64("ring_shm")
closest = ts.find_closest(target_ns)
interp = ts.find_interpolation_pair(target_ns)
Temporal Query Safety
Two layers of protection against unit/clock-type mismatches:
Layer 1: Runtime — max_distance parameter
// BUG: querying with milliseconds (5000) instead of nanoseconds
auto bad = ts.find_closest(5000); // silently returns oldest element
auto bad = ts.find_closest(5000, 100'000'000); // returns nullopt — mismatch caught!
// CORRECT: consistent nanosecond units
auto good = ts.find_closest(5'000'000'000, 100'000'000); // works, within 100ms
Layer 2: Compile-time — SanitizedKey<Tag> (opt-in)
SanitizedKey<Tag> is a strong type that can only be created through an external validator function. The compiler prevents passing raw uint64_t where SanitizedKey is expected.
#include "safe-shm/sanitized_key.hpp"
// Step 1: Sanitize — the ONLY way to create a SanitizedKey
auto key = safe_shm::sanitize<safe_shm::MonotonicNsTag>(
raw_ns, safe_shm::MonotonicNsValidator{});
if (!key) { /* rejected: wrong units or clock type */ }
// Step 2: Pass to TimeSeries — type-safe overload
auto result = ts.find_closest(*key);
auto interp = ts.find_interpolation_pair(*key);
auto fresh = ts.get_latest_if_fresh(*key);
Built-in validators:
| Validator | Catches |
|---|---|
MonotonicNsValidator{} |
Values that aren't plausible CLOCK_MONOTONIC nanoseconds |
RangeValidator{min, max} |
Values outside expected range |
ProximityValidator{ref, tol} |
Values differing from reference by > tolerance |
AllOf(v1, v2, ...) |
Composes validators with AND logic |
Different Tag types make different sanitization policies type-incompatible at compile time — SanitizedKey<MonotonicNsTag> cannot be passed where SanitizedKey<RangeCheckedTag> is expected.
Custom validators are just callables:
auto key = safe_shm::sanitize<MyTag>(raw_ns, [latest_ts](uint64_t v) {
return (v > latest_ts ? v - latest_ts : latest_ts - v) <= 2'000'000'000ULL;
});
The raw uint64_t API is unchanged — SanitizedKey is purely opt-in.
Build
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
ctest
Sanitizers
cmake .. -DSANITIZER=asan # Address + UB (default)
cmake .. -DSANITIZER=tsan # Thread sanitizer
cmake .. -DSANITIZER=none # No sanitizer
Fuzz Testing
# Requires clang
CC=clang CXX=clang++ cmake .. -DSANITIZER=fuzzer
make fuzz_cyclic_buffer fuzz_time_series
./fuzz_cyclic_buffer corpus_cyclic/ -max_total_time=60
./fuzz_time_series corpus_ts/ -max_total_time=60
Docker (CI)
docker build -t safe-shm-test -f Dockerfile.test .
docker run --rm -v $(pwd):/src safe-shm-test bash -c \
"cd /tmp && cmake /src -DSANITIZER=none && make -j\$(nproc) && ctest"
Examples
All examples are buildable targets — see examples/ directory.
| Example | Language | What it demonstrates |
|---|---|---|
seqlock_example |
C++ | Cross-process writer/reader with blocking reads |
cyclic_buffer_example |
C++ | Ring buffer + Stamped + TimeSeries temporal queries |
lifecycle_example |
C++ | OwnedShm RAII, heartbeat, cleanup utilities |
python_seqlock.py |
Python | Seqlock read/write + Stamped + monotonic clock |
python_cyclic_buffer.py |
Python | CyclicBuffer + TimeSeries from Python |
# C++ examples (two terminals)
./seqlock_example writer # terminal 1
./seqlock_example reader # terminal 2
# Python examples
PYTHONPATH=build python3 examples/python_seqlock.py
PYTHONPATH=build python3 examples/python_cyclic_buffer.py
Tests
| Test | Type | Assertions | What it covers |
|---|---|---|---|
flat_type_test |
Unit | — | FlatType concept acceptance/rejection |
double_buffer_swapper_test |
Unit | — | Swap mechanics, structs, large arrays |
swap_runner_test |
Unit | — | Trigger/wait, exceptions, concurrent threads |
safe_shm_test |
Integration | — | Storage + DblBufLoader round-trip |
shared_memory_test |
Integration | — | SharedMemory typed wrapper |
image_shm_test |
Integration | — | DoubleBufferShm with FHD images |
integration_test |
Integration | — | Cross-process (fork) all components |
seqlock_test |
Integration | — | Seqlock store/load, cross-process, concurrent, blocking |
stamped_test |
Integration | 28 | Stamped layout, stamp(), monotonic clock, ShmStats |
cyclic_buffer_test |
Integration | 24,252 | Insert/get, overflow, structs, cross-process, concurrent |
time_series_test |
Integration | 66 | Binary search, interpolation, freshness, edge cases, unit confusion |
shm_lifecycle_test |
Integration | 28 | OwnedShm, ShmHeader, heartbeat, liveness detection |
cross_process_test |
Integration | 69 | All producer/consumer combos, 1-writer-3-readers, FHD images |
sanitized_key_test |
Integration | 41 | SanitizedKey construction, validators, tag safety, TimeSeries integration |
Benchmarks
Run with: ./benchmark && ./benchmark_competitors (built with -O3 -DNDEBUG, nanobench)
Throughput (store + load cycle)
| Method | 64 B | 4 KB | 1 MB | FHD RGB (6 MB) |
|---|---|---|---|---|
| memcpy (baseline) | 55-60 GB/s | 120-125 GB/s | 26-29 GB/s | 36 GB/s |
| raw POSIX shm (no sync) | 63 GB/s | 128 GB/s | 28 GB/s | 35 GB/s |
| Seqlock (lock-free) | 0.4 GB/s | 9.3 GB/s | 9.2 GB/s | 38 GB/s |
| CyclicBuffer (per-slot seqlock) | 0.4 GB/s | 11.5 GB/s | 9.1 GB/s | 39 GB/s |
| DoubleBufferShm (futex) | ~6 MB/s | 0.15 GB/s | 6.8 GB/s | 12 GB/s |
| POSIX mq (kernel IPC) | 0.16 GB/s | 7.4 GB/s | — | — |
| Unix domain socket | 0.13 GB/s | 6.2 GB/s | — | — |
| pipe (kernel IPC) | 0.17 GB/s | 9.4 GB/s | 8.4 GB/s | — |
TimeSeries Query Latency
| Operation | Latency | Throughput |
|---|---|---|
find_closest (binary search, 64 elements) |
45 ns | 22 Mop/s |
find_interpolation_pair |
66 ns | 15 Mop/s |
get_latest_if_fresh |
11 ns | 91 Mop/s |
Key Takeaways
- CyclicBuffer at FHD: 39 GB/s — matches raw memcpy with full ring buffer history
- Seqlock vs CyclicBuffer: equivalent at small payloads, CyclicBuffer slightly faster at 4 KB
- vs kernel IPC: 2.7x faster than pipe at 64 B, 60x faster than POSIX mq at 4 KB
- TimeSeries lookups: 45 ns per binary search across 64 elements — suitable for real-time control loops
- Zero-copy: no intermediate buffers, no kernel transitions, no thread wakeups on read path
Design Decisions
Per-slot seqlock — Each CyclicBuffer slot has its own 32-bit sequence counter. Readers on slot i never contend with writers on slot j. The alternative (single global seqlock) forces retry on any concurrent write.
Power-of-two capacity — N & (N-1) == 0 enables bitmask modulo (idx & (N-1)) instead of expensive integer division. Enforced at compile time via static_assert.
Stamped<T> composability — Stamped<T> is itself a FlatType, so Seqlock<Stamped<SensorData>>, CyclicBuffer<Stamped<IMU>, 64>, and OwnedShm<Stamped<Config>> all work without adapter code.
std::optional return types — try_get(), find_closest(), find_interpolation_pair() return std::optional<T> instead of throwing. Compatible with std::expected patterns and real-time constraints (no heap allocation).
Futex for blocking — wait_for_write() and load_blocking() use raw FUTEX_WAIT/FUTEX_WAKE (not _PRIVATE) for cross-process signaling. Uncontended path is a single atomic compare — no syscall.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file safe_shm-0.1.0.tar.gz.
File metadata
- Download URL: safe_shm-0.1.0.tar.gz
- Upload date:
- Size: 60.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b4133954a1f15fd95b0bb2134f26da7462aa64514b6e62dd03dc5937d6d09201
|
|
| MD5 |
db7ce18de318f78f39ceea0059e44e7f
|
|
| BLAKE2b-256 |
d48986381d3a259caab060c635ea99c308acc22995420e06339473e3303cf22c
|
Provenance
The following attestation bundles were made for safe_shm-0.1.0.tar.gz:
Publisher:
pypi.yml on PavelGuzenfeld/safe-shm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safe_shm-0.1.0.tar.gz -
Subject digest:
b4133954a1f15fd95b0bb2134f26da7462aa64514b6e62dd03dc5937d6d09201 - Sigstore transparency entry: 1085469587
- Sigstore integration time:
-
Permalink:
PavelGuzenfeld/safe-shm@27edc071649b593d55f06bcc2fb7970804d73c43 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/PavelGuzenfeld
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@27edc071649b593d55f06bcc2fb7970804d73c43 -
Trigger Event:
push
-
Statement type:
File details
Details for the file safe_shm-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: safe_shm-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 294.0 kB
- Tags: CPython 3.13, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e430aba9aaaeecf2a54de7c9652c70ea2215f2162e525627ff54234962b7f5e7
|
|
| MD5 |
b3543216bb793f1209079f28dc7ede50
|
|
| BLAKE2b-256 |
2346dc1071b5b315b3ca74edb5d535c78415bbc6d824843f0ff5b4ce05fe9234
|
Provenance
The following attestation bundles were made for safe_shm-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:
Publisher:
pypi.yml on PavelGuzenfeld/safe-shm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safe_shm-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
e430aba9aaaeecf2a54de7c9652c70ea2215f2162e525627ff54234962b7f5e7 - Sigstore transparency entry: 1085469802
- Sigstore integration time:
-
Permalink:
PavelGuzenfeld/safe-shm@27edc071649b593d55f06bcc2fb7970804d73c43 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/PavelGuzenfeld
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@27edc071649b593d55f06bcc2fb7970804d73c43 -
Trigger Event:
push
-
Statement type:
File details
Details for the file safe_shm-0.1.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: safe_shm-0.1.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 273.8 kB
- Tags: CPython 3.13, manylinux: glibc 2.27+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ced4e2372022f406dd55053e6c8330fd0ac889ec23c1c1ee92cb7d22e92dc55
|
|
| MD5 |
1b1054ac49cc6f76c4edffb69160a2da
|
|
| BLAKE2b-256 |
2b085fe2dcb53586056185548740d91f16ca04ca26860af5654e3bac02997809
|
Provenance
The following attestation bundles were made for safe_shm-0.1.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl:
Publisher:
pypi.yml on PavelGuzenfeld/safe-shm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safe_shm-0.1.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl -
Subject digest:
9ced4e2372022f406dd55053e6c8330fd0ac889ec23c1c1ee92cb7d22e92dc55 - Sigstore transparency entry: 1085470134
- Sigstore integration time:
-
Permalink:
PavelGuzenfeld/safe-shm@27edc071649b593d55f06bcc2fb7970804d73c43 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/PavelGuzenfeld
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@27edc071649b593d55f06bcc2fb7970804d73c43 -
Trigger Event:
push
-
Statement type:
File details
Details for the file safe_shm-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: safe_shm-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 294.1 kB
- Tags: CPython 3.12, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
baf2d61575bde36b486feba922a2bf1a33a892c509a14fe948ee390533e7c441
|
|
| MD5 |
5635845ebea8c1de8e8fee38a4c330d1
|
|
| BLAKE2b-256 |
c88c0312b131d585568e53d8c9effef381273e818d9d218d1a28f2888a9b3530
|
Provenance
The following attestation bundles were made for safe_shm-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:
Publisher:
pypi.yml on PavelGuzenfeld/safe-shm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safe_shm-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
baf2d61575bde36b486feba922a2bf1a33a892c509a14fe948ee390533e7c441 - Sigstore transparency entry: 1085469635
- Sigstore integration time:
-
Permalink:
PavelGuzenfeld/safe-shm@27edc071649b593d55f06bcc2fb7970804d73c43 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/PavelGuzenfeld
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@27edc071649b593d55f06bcc2fb7970804d73c43 -
Trigger Event:
push
-
Statement type:
File details
Details for the file safe_shm-0.1.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: safe_shm-0.1.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 273.9 kB
- Tags: CPython 3.12, manylinux: glibc 2.27+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26a2b2d28c8d2deedad56c191ec133144ef2b5bbe3cb378841daa490a4099a00
|
|
| MD5 |
a8bd532bc0ee7c5c054e84ec2f64e339
|
|
| BLAKE2b-256 |
8ef38fb5f56e660437095003b3eed66e7e3ed5591f23a3587e7a08aff3426429
|
Provenance
The following attestation bundles were made for safe_shm-0.1.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl:
Publisher:
pypi.yml on PavelGuzenfeld/safe-shm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safe_shm-0.1.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl -
Subject digest:
26a2b2d28c8d2deedad56c191ec133144ef2b5bbe3cb378841daa490a4099a00 - Sigstore transparency entry: 1085470074
- Sigstore integration time:
-
Permalink:
PavelGuzenfeld/safe-shm@27edc071649b593d55f06bcc2fb7970804d73c43 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/PavelGuzenfeld
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@27edc071649b593d55f06bcc2fb7970804d73c43 -
Trigger Event:
push
-
Statement type:
File details
Details for the file safe_shm-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: safe_shm-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 296.2 kB
- Tags: CPython 3.11, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
09322813ce3a8f6a9bdd66d82fc81f0fbdb91b14cac6cbac4e50ee672bb1dc50
|
|
| MD5 |
c75598788c208f6d7de43f598c344a6c
|
|
| BLAKE2b-256 |
dfcd6f9919d526e0d871a4f66d59c1bdc3d65934ad2821b06d035bf7878e8f7e
|
Provenance
The following attestation bundles were made for safe_shm-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:
Publisher:
pypi.yml on PavelGuzenfeld/safe-shm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safe_shm-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
09322813ce3a8f6a9bdd66d82fc81f0fbdb91b14cac6cbac4e50ee672bb1dc50 - Sigstore transparency entry: 1085469852
- Sigstore integration time:
-
Permalink:
PavelGuzenfeld/safe-shm@27edc071649b593d55f06bcc2fb7970804d73c43 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/PavelGuzenfeld
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@27edc071649b593d55f06bcc2fb7970804d73c43 -
Trigger Event:
push
-
Statement type:
File details
Details for the file safe_shm-0.1.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: safe_shm-0.1.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 275.9 kB
- Tags: CPython 3.11, manylinux: glibc 2.27+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5145683394125b4ee2777b7590a2c766b88af204b08b8f1813a9e3b89aee6199
|
|
| MD5 |
eeb0ceaa23f5391846a36d00cf2c0c22
|
|
| BLAKE2b-256 |
932d2bd606b2f5ecf1440a01c11ee48d09e1b97566181600972ae0c2036a4e97
|
Provenance
The following attestation bundles were made for safe_shm-0.1.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl:
Publisher:
pypi.yml on PavelGuzenfeld/safe-shm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safe_shm-0.1.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl -
Subject digest:
5145683394125b4ee2777b7590a2c766b88af204b08b8f1813a9e3b89aee6199 - Sigstore transparency entry: 1085469982
- Sigstore integration time:
-
Permalink:
PavelGuzenfeld/safe-shm@27edc071649b593d55f06bcc2fb7970804d73c43 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/PavelGuzenfeld
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@27edc071649b593d55f06bcc2fb7970804d73c43 -
Trigger Event:
push
-
Statement type:
File details
Details for the file safe_shm-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: safe_shm-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 296.7 kB
- Tags: CPython 3.10, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a414491cc4d97b7be42d428940de325ad2fdccc2946d7c063f5f601c48967772
|
|
| MD5 |
68b51436ca13b1c96f221d52494025d5
|
|
| BLAKE2b-256 |
28d2b1856909ff503e95bb40870ddc893ba4b960c6781e81d5d0ef69b4605add
|
Provenance
The following attestation bundles were made for safe_shm-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:
Publisher:
pypi.yml on PavelGuzenfeld/safe-shm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safe_shm-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
a414491cc4d97b7be42d428940de325ad2fdccc2946d7c063f5f601c48967772 - Sigstore transparency entry: 1085470016
- Sigstore integration time:
-
Permalink:
PavelGuzenfeld/safe-shm@27edc071649b593d55f06bcc2fb7970804d73c43 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/PavelGuzenfeld
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@27edc071649b593d55f06bcc2fb7970804d73c43 -
Trigger Event:
push
-
Statement type:
File details
Details for the file safe_shm-0.1.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: safe_shm-0.1.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 276.4 kB
- Tags: CPython 3.10, manylinux: glibc 2.27+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f31f06f83735a2c1aa407bcb36f10f28c761896f1653dd82546a913f029d542
|
|
| MD5 |
509ca050fc7e26d667030b0988f1f5d2
|
|
| BLAKE2b-256 |
7e99a479a129addc482b30cff7cac736e884911a1bb05d9bd3e4e23fde252b93
|
Provenance
The following attestation bundles were made for safe_shm-0.1.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl:
Publisher:
pypi.yml on PavelGuzenfeld/safe-shm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safe_shm-0.1.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl -
Subject digest:
3f31f06f83735a2c1aa407bcb36f10f28c761896f1653dd82546a913f029d542 - Sigstore transparency entry: 1085469716
- Sigstore integration time:
-
Permalink:
PavelGuzenfeld/safe-shm@27edc071649b593d55f06bcc2fb7970804d73c43 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/PavelGuzenfeld
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@27edc071649b593d55f06bcc2fb7970804d73c43 -
Trigger Event:
push
-
Statement type:
File details
Details for the file safe_shm-0.1.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: safe_shm-0.1.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 297.2 kB
- Tags: CPython 3.9, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ce503577c0fb20df56f366526b550c67e363acddf69c23277bf2b209f8184f4
|
|
| MD5 |
8295878e6c448264287defac7fb47692
|
|
| BLAKE2b-256 |
aad0f85b8502a9d541b9d5eac0ec1625e0d5191de17071baa18fb2a0e3667503
|
Provenance
The following attestation bundles were made for safe_shm-0.1.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:
Publisher:
pypi.yml on PavelGuzenfeld/safe-shm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safe_shm-0.1.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
1ce503577c0fb20df56f366526b550c67e363acddf69c23277bf2b209f8184f4 - Sigstore transparency entry: 1085469890
- Sigstore integration time:
-
Permalink:
PavelGuzenfeld/safe-shm@27edc071649b593d55f06bcc2fb7970804d73c43 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/PavelGuzenfeld
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@27edc071649b593d55f06bcc2fb7970804d73c43 -
Trigger Event:
push
-
Statement type:
File details
Details for the file safe_shm-0.1.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: safe_shm-0.1.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 276.7 kB
- Tags: CPython 3.9, manylinux: glibc 2.27+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4728d956c6c465708b8e5e7738e024de13656762856ab8fdaf1f95ec26abd5d5
|
|
| MD5 |
7c0918611554db09fc8d4b0717f0d14d
|
|
| BLAKE2b-256 |
9a45c254233f357a8171cc5d325ed5ad1465ace6a3f924c9f380e56eb9e31a97
|
Provenance
The following attestation bundles were made for safe_shm-0.1.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl:
Publisher:
pypi.yml on PavelGuzenfeld/safe-shm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safe_shm-0.1.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl -
Subject digest:
4728d956c6c465708b8e5e7738e024de13656762856ab8fdaf1f95ec26abd5d5 - Sigstore transparency entry: 1085469948
- Sigstore integration time:
-
Permalink:
PavelGuzenfeld/safe-shm@27edc071649b593d55f06bcc2fb7970804d73c43 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/PavelGuzenfeld
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@27edc071649b593d55f06bcc2fb7970804d73c43 -
Trigger Event:
push
-
Statement type: