summaryrefslogtreecommitdiff
path: root/lib/Thread/Queue/Event.pm
blob: 3d82c4d04b87ae915a4909d6501de1eea70d146a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package Thread::Queue::Event; 
use Moose;
use Glib;
use Thread::Queue;
use Carp;
 
has queue => (
    is => 'ro',
    isa => 'Thread::Queue',
    init_arg => undef,
    builder => '_build_queue',
    handles => [qw(
                      enqueue
                      dequeue
                      dequeue_nb
                      pending
                      peek
                      insert
                      extract
              )],
);
 
has pipes => (
    isa => 'ArrayRef',
    is => 'ro',
    builder => '_build_pipes',
);
 
sub _build_pipes {
    my ($main,$thread);pipe($main,$thread);
 
    return [$main,$thread];
}
 
sub _build_queue {
    return Thread::Queue->new();
}
 
sub _pipe_write {
    return syswrite $_[0]->pipes->[1],'0';
}
 
sub _pipe_read {
    my $foo;sysread $_[0]->pipes->[0],$foo,1;
    return $foo;
}
 
sub event_fh {
    return $_[0]->pipes->[0];
}
 
sub event_fileno {
    return fileno($_[0]->event_fh);
}
 
after enqueue => \&_pipe_write;
 
before dequeue => \&_pipe_read;
 
sub signal {
    my ($self)=@_;
 
    croak "Not signaling on an empty queue, would block"
        unless $self->pending;
 
    $self->_pipe_write();
}
 
sub with_role {
    my ($self,$role)=@_;
 
    if ($role !~ /::/) {
        $role="Thread::Queue::Event::$role";
    }
 
    Class::MOP::load_class($role);
 
    $role->meta->apply($self);
 
    return $self;
}
 
no Moose;
1;