NAME
Acme::Parataxis::Sync - Base Class for Fiber Synchronization Primitives
SYNOPSIS
use v5.40;
use Acme::Parataxis qw[async fiber];
use Acme::Parataxis::Sync::Mutex;
use Acme::Parataxis::Sync::WaitGroup;
my $lock = Acme::Parataxis::Sync::Mutex->new;
my $group = Acme::Parataxis::Sync::WaitGroup->new;
async {
$group->add(4);
for my $id ( 1 .. 4 ) {
fiber {
my $guard = $lock->guard; # mutex held for scope of $guard
perform_exclusive_operation($id);
$group->done;
};
}
$group->wait; # parks until all 4 workers call done()
say 'All workers completed safely!';
};
DESCRIPTION
Acme::Parataxis::Sync is the abstract base class powering the Parataxis synchronization primitive family:
Acme::Parataxis::Sync::Mutex - Non-reentrant mutual exclusion locks with owner tracking and scope guards.
Acme::Parataxis::Sync::RwLock - Writer-preferring reader/writer locks with shared and exclusive guards.
Acme::Parataxis::Sync::WaitGroup - Concurrency counters that block until tasks decrement to zero.
Acme::Parataxis::Sync::Barrier - Fixed-party phase rendezvous gates.
Acme::Parataxis::Sync::Once - Thread-safe, single-execution initializers.
All primitives share uniform operational guarantees:
Scheduled cooperative parking: Waiting fibers suspend cleanly in the scheduler; neither the OS thread nor the event loop is ever blocked.
Context validation: Methods that manage locks or waits resolve the calling fiber's ID immediately via
_fid(), croaking with a descriptive error if called outside a scheduled fiber.Safe wait unwinding: Every wait is interruptible via with_timeout and cancellation tokens. When an interrupted wait unwinds, the primitive dequeues the fiber so stale wakeups never target reused fiber IDs.
SUBCLASS CONTRACT
The base class provides internal helpers for implementing custom synchronization objects:
_fid( $croak_message )
Returns the numeric fiber ID of the currently executing fiber. If called from outside a scheduled fiber, croaks with $croak_message.
_park( $reason, [$dereg_coderef] )
Parks the calling fiber in the scheduler with diagnostic label $reason. If the park is interrupted by a timeout or cancellation, $dereg_coderef is executed immediately to clean up wait queues.
_wake( $fiber_id )
Re-enqueues the fiber with ID $fiber_id onto the scheduler run queue. If the fiber has already been destroyed or reaped, the wake is safely dropped.
How Contended Waits Work
Contended acquisitions in Parataxis follow a strict four-stage cycle:
Resolve the fiber ID: Verify the calling fiber exists via
_fid().Evaluate immediate acquisition: Uncontended locks, matching phases, or positive counts resolve immediately without touching scheduler queues.
Queue and park: The fiber ID and an unregister callback are added to the primitive's FIFO queue, and the fiber parks. If interrupted, the callback cleans the queue.
Atomic hand-off: When a releasing fiber calls
unlock()ordone(), ownership is assigned to the next waiter before the waiter is enqueued. This prevents third-party fibers from stealing the resource before the woken waiter runs.
Behavior Notes
Locks outlive fibers
If a fiber acquires a
MutexorRwLockand terminates without callingunlock(), the lock remains held permanently. Always use scoped guards (guard,read_guard,write_guard) to guarantee release upon scope exit or exception unwinding.Guards cannot cross fibers
Guards verify that the releasing fiber matches the acquiring fiber upon destruction. Passing a guard object to another fiber will cause the guard's destructor to croak and strand the lock.
Off-fiber arithmetic
WaitGroup-add> andWaitGroup-done> perform plain counter arithmetic and are safe to call outside a scheduled fiber. All methods that actually park (such aswait,lock, andarrive_and_wait) require an active fiber.
SEE ALSO
Acme::Parataxis, Acme::Parataxis::Sync::Mutex, Acme::Parataxis::Sync::RwLock, Acme::Parataxis::Sync::WaitGroup, Acme::Parataxis::Sync::Barrier, Acme::Parataxis::Sync::Once
AUTHOR
Sanko Robinson https://github.com/sanko
LICENSE
Copyright (C) Sanko Robinson.
This library is free software; you can redistribute it and/or modify it under the terms found in the Artistic License 2.