NAME

Acme::Parataxis::Semaphore - A counting semaphore for fiber synchronization

SYNOPSIS

use Acme::Parataxis;
use Acme::Parataxis::Semaphore;

my $sem = Acme::Parataxis::Semaphore->new;   # unlocked by default

async {
    fiber { $sem->down };   # wait for a signal
    $sem->up;
};

DESCRIPTION

A simple integer counter that optionally blocks fibers when it reaches zero. There is no owner associated with a semaphore, so one fiber can down it while another can up it, up may be called before down, and so on.

Blocked fibers are parked (they do not busy-wait) and are resumed in FIFO order as permits become available, exactly like the futures used by await.

CONSTRUCTOR

new( [...] )

my $sem = Acme::Parataxis::Semaphore->new;
my $sem = Acme::Parataxis::Semaphore->new(count => 3);

Creates a new semaphore. The optional count parameter sets the initial number of permits and defaults to 1.

METHODS

down( )

$sem->down;

Acquire a permit. If the count is zero, the current fiber is suspended until a permit becomes available. Decrements the count upon success.

up( )

$sem->up;

Release a permit. Increments the count and wakes one blocked waiter if any are queued.

try( )

my $acquired = $sem->try;

Attempt to acquire a permit without blocking. Returns true and decrements the count if a permit is available; returns false immediately otherwise. This is useful when you want to opportunistically grab a permit but don't want to stall the fiber.

adjust( $diff )

$sem->adjust($diff);

Adjust the permit count by $diff (which may be negative). Wakes up to $diff blocked waiters if the new count is positive. This is useful for bulk-release scenarios, such as unblocking a channel.

wait( )

$sem->wait;

Block until a permit is available. This is equivalent to down but is named for consistency with other Acme::Parataxis synchronization primitives.

guard

my $guard = $sem->guard( );

Acquire a permit and return an Acme::Parataxis::Semaphore::Guard object. The permit is automatically released when the guard object goes out of scope (unless the interpreter is in global destruction). This is a convenient way to ensure cleanup.

{
    my $guard = $sem->guard;
    # permits are held here
}
# $sem->up called automatically

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.