Perl6-Pugs

 view release on metacpan or  search on metacpan

docs/Perl6/Spec/Concurrency.pod  view on Meta::CPAN

my $thr = async {
    ...do something...
    END { }
};

Conc::Thread.this
Conc::Proc.this

Conc object # name is still up for grabs!
- numify to TIDs (as in pugs)
- stringify to something sensible (eg. "<Conc:tid=5>");
- enumerable with Conc.list
- Conc.yield (if this is to live but deprecated, maybe call it sleep(0)?)
- sleep() always respects other threads, thank you very much
- standard methods:
    - .join    # wait for invocant to finish (always item cxt)
    - .die     # throw exception in the invocant thread
    - .alarm   # set up alarms
    - .alarms  # query existing alarms
    - .suspend # pause a thread; fail if already paused
    - .resume  # revive a thread; fail if already running
    - .detach  # survives parent thread demise (promoted to process)
               # process-local changes no longer affects parent
               # tentatively, the control methods still applies to it
               # including wait (which will always return undef)
               # also needs to discard any atomicity context
- attributes:
    - .started  # time
    - .finished # time
    - .waiting  # suspened (not diff from block on wakeup signal)
                # waiting on a handle, a condition, a lock, et cetera
                # otherwise returns false for running threads
                # if it's finished then it's undef(?)
    - .current_continuation
                # the CC currently running in that thread

- "is throttled" trait

    method throttled::trait_auxillary:<is> ($limit=1, :$key=gensym()) {
        # "is throttled" limits max connection to this Code object
        # the throttling is shared among closures with the same key
        # the limit may differ on closures with the same key.
        # if the counter with the "key" equals or exceeds a closure's limit,
        # the closure can't be entered until it's released
        # (this can be trivially implmented using atomic+retry)
    }

    class Foo {
        method a is throttled(:limit(3) :key<blah>) { ... }
        method b is throttled(:limit(2) :key<blah>) { ... }
    }
    my Foo $f .= new;
    async { $f.a }
    async { $f.b }

- Thread::Status
- IO objects and containers gets concurrency love!
    - $obj.wake_on_readable
    - $obj.wake_on_writable
    - $obj.wake_on_either_readable_or_writable_or_passed_time(3); # fixme fixme
    - $obj.wake_on:{.readable} # busy wait, probably

    my @a is Array::Chan = 1..Inf;
    async { @a.push(1) };
    async { @a.blocking_shift({ ... }) };
    async { @a.unshift({ ... }) };

Communication abstractions
- shared, transactional variables by default

# program will wait for _all_ threads
# unjoined threads will be joined at the beginning of the END block batch
# of the parent thread that spawned them

### INTERFACE BARRIER ###
module Blah;
{

    is atomic;   # retry/orelse/whatever other rollback stuff
                 # limitation: no external IO (without lethal warnings anyway)
                 # can't do anything irreversible

    is critical; # free to do anything irreversible
                 # means "don't interrupt me"
                 # in system with critical section, no interrupts from
                 # other threads will happen during execution
                 # you can't suspend me

    my $boo is export;
    $boo = 1;

    # We decree that this part forms the static interface
    # it's run once during initial compilation under the
    # Separate Compilation doctrine and the syms sealed off
    # to form part fo bytecode syms headers
    %CALLER::<&blah> = { 1 }; # work - adds to export set
    die "Eureka!" if %CALLER::<$sym>; # never dies

    # BEGIN { $boo = time };

    sub IMPORT {
        # VERY DYNAMIC!

        our $i = time;
        %CALLER::<&blah> = { 1 }; # work - adds to export set
        die "Eureka!" if %CALLER::<$sym>; # probes interactively
    }
}
### INTERFACE BARRIER ###

my $sym;
threads.new({
    use Blah;
    BEGIN { require(Blah).import }

    my $boo; BEGIN { eval slurp<Blah.pm>; $boo := $Blah::boo };

    ...
});

=head2 Signals



( run in 2.124 seconds using v1.01-cache-2.11-cpan-5c0b1e786e0 )