package Glib::Thread::Queue;
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 add_watch {
my ($self,$sub)=@_;
Glib::IO->add_watch($self->event_fileno,'in',$sub);
}
sub signal {
my ($self)=@_;
croak "Not signaling on an empty queue, would block"
unless $self->pending;
$self->_pipe_write();
}
no Moose;
1;