PageRenderTime 21ms CodeModel.GetById 1ms app.highlight 15ms RepoModel.GetById 2ms app.codeStats 0ms

/lib/Teto/Coro/MarkedChannel.pm

http://github.com/motemen/Teto
Perl | 45 lines | 33 code | 12 blank | 0 comment | 3 complexity | 66b631dc163d1af578799904c09769d4 MD5 | raw file
 1package Teto::Coro::MarkedChannel;
 2use strict;
 3use warnings;
 4use Mouse;
 5use Coro::Semaphore;
 6
 7has size => ( is => 'rw', isa => 'Int', default => sub { 1 } );
 8has data => ( is => 'rw', isa => 'ArrayRef', default => sub { [] } );
 9
10has read_sem => ( is => 'rw', default => sub { Coro::Semaphore->new(0) } );
11has mark_sem => ( is => 'rw', default => sub { Coro::Semaphore->new($_[0]->size) } );
12
13no Mouse;
14
15__PACKAGE__->meta->make_immutable;
16
17use constant MARK => \0;
18
19sub put {
20    my ($self, $data) = @_;
21    push @{ $self->data }, $data;
22    $self->read_sem->up;
23}
24
25sub put_mark {
26    my $self = shift;
27    $self->put(MARK);
28    $self->mark_sem->down;
29}
30
31sub get {
32    my $self = shift;
33
34    $self->read_sem->down;
35
36    my $data = shift @{ $self->data };
37    if (ref $data && $data == MARK) {
38        $self->mark_sem->up;
39        return $self->get;
40    }
41
42    return $data;
43}
44
451;