internal/path_c_admit¶
Internal module
lockfree/internal/path_c_admit is an internal module. Its
API is not part of the umbrella's semver contract and may change
at any time. Downstream code MUST NOT import it directly.
Documented here for contributors and reviewers.
path_c_admit implements the unbounded MPMC "path C — admit" branch
of the consumer-side close protocol: the case where the consumer
observes an empty cell and must close the cell so that the producer
sees the closure and retries on the next segment. See the LCRQ
paper §4 for the broader protocol context.
See also¶
path_c_wrap— sibling close-CAS branch.- Queue — the body that dispatches into these paths.
path_c_admit
¶
Path-C admission dispatch — the user-facing T type-class gate that
sits at the head of every Queue / BQueue push, pop, drain entry
point.
Behaviour¶
- Path-C string / seq handling (no
ManagedSliceindirection). when T is ref:composition matrix (25 rows; verbatim REJECT messages for rows 7 and 8).- Nullable T handling (
nilpassthrough — not a reject). - ref T rejection rules (canonical
when/elifchain shape). - mm:none + ref T contract details (pure bit transport).
- ManagedRef[X] shim impl details (per-MM inc/dec wrappers).
- Path-C string / seq inline transfer-ownership:
sink string/sink seq[U]flow through the slot'sPair.secondhalf. Per-MM treatment lives at the call site inside the queue's push/pop body; this admission template only validates the type-class.
Why a template, not a when block inlined at every call site¶
The reject/accept chain repeats VERBATIM at every user-facing push,
pop, and drain entry across both queue.nim and bqueue.nim.
Inlining it 14+ times would bake the REJECT messages into copies that
drift the moment someone updates one and forgets the others.
Centralising it in one template makes the matrix the single source of
truth.
The template expands to a when chain that emits either a compile-time
{.error.} (REJECT rows + unsupported fallback) or expands to nothing
(ACCEPT rows).
NOT user-facing¶
This module is an internal implementation detail. Users see only the
Queue / BQueue types and their push/pop/drain APIs.
hasManagedFields compileTime ¶
proc hasManagedFields(T: typedesc): bool
pathCAdmit ¶
template pathCAdmit(T: typedesc)
Static dispatch / admission gate for Queue[T, ...] and
BQueue[T, ...] push, pop, drain entries.
Emits compile-time {.error.} for the REJECT rows (distinct
ref alias row 7, nested ref ref row 8, value types with managed
fields) and the unsupported-T fallback. Accept rows
(ref T, string, seq[U], POD) expand to nothing; their
per-MM lifecycle handling lives at the call site below.
The chain ORDER MATTERS. Reject arms must come BEFORE accept arms so
a ref ref Foo does not match the plain T is ref accept arm by way
of "outer ref still matches is ref."
Row order verification:
T is ref and (T is ref ref ...)reject arm matches nested refs.T is refplain accept arm fires only for directrefto a non-ref user type, never forref ref.T is distinct and distinctBase(T) is refreject arm matches distinct-of-ref aliases. PlainT is distinctdoes not match non-distinct types so the downstreamT is refaccept arm catches exactly the intended population.
Nullable note: nil for ref T, ptr T, pointer, and
cstring is ACCEPTED (slot bits = 0, disambiguated by the seq
counter / committed flag at the slot-state predicate layer). The
admit chain does NOT reject nil.
Parameters
-
T(typedesc)