Commit | Line | Data |
31a246e4 |
1 | package Tak::Loop; |
2 | |
77bf1d9b |
3 | use IO::Select; |
31a246e4 |
4 | use Moo; |
5 | |
77bf1d9b |
6 | has is_running => (is => 'rw', clearer => 'loop_stop'); |
7 | |
8 | has _read_watches => (is => 'ro', default => sub { {} }); |
9 | has _read_select => (is => 'ro', default => sub { IO::Select->new }); |
10 | |
11 | sub watch_io { |
12 | my ($self, %watch) = @_; |
13 | my $fh = $watch{handle}; |
14 | if (my $cb = $watch{on_read_ready}) { |
15 | $self->_read_select->add($fh); |
16 | $self->_read_watches->{$fh} = $cb; |
17 | } |
18 | } |
19 | |
20 | sub unwatch_io { |
21 | my ($self, %watch) = @_; |
22 | my $fh = $watch{handle}; |
23 | if ($watch{on_read_ready}) { |
24 | $self->_read_select->remove($fh); |
25 | delete $self->_read_watches->{$fh}; |
26 | } |
27 | } |
28 | |
29 | sub loop_once { |
30 | my ($self) = @_; |
31 | my $read = $self->_read_watches; |
986f5290 |
32 | my ($readable) = IO::Select->select($self->_read_select, undef, undef, 0.5); |
2791fd73 |
33 | # I would love to trap errors in the select call but IO::Select doesn't |
34 | # differentiate between an error and a timeout. |
35 | # -- no, love, mst. |
77bf1d9b |
36 | foreach my $fh (@$readable) { |
37 | $read->{$fh}(); |
38 | } |
39 | } |
40 | |
41 | sub loop_forever { |
42 | my ($self) = @_; |
43 | $self->is_running(1); |
44 | while ($self->is_running) { |
45 | $self->loop_once; |
46 | } |
47 | } |
48 | |
31a246e4 |
49 | 1; |