return $timeout;
}
+sub event_step ($) {
+ my ($self) = @_;
+ return if $self->{closed};
+
+ my $wbuf = $self->{wbuf};
+ if (@$wbuf) {
+ $self->event_write;
+ return if $self->{closed} || scalar(@$wbuf);
+ }
+
+ # only read more requests if we've drained the write buffer,
+ # otherwise we can be buffering infinitely w/o backpressure
+ $self->event_read;
+}
+
### The epoll-based event loop. Gets installed as EventLoop if IO::Epoll loads
### okay.
sub EpollEventLoop {
# that ones in the front triggered unregister-interest actions. if we
# can't find the %sock entry, it's because we're no longer interested
# in that event.
- my PublicInbox::DS $pob = $DescriptorMap{$ev->[0]};
- my $code;
- my $state = $ev->[1];
-
- DebugLevel >= 1 && $class->DebugMsg("Event: fd=%d (%s), state=%d \@ %s\n",
- $ev->[0], ref($pob), $ev->[1], time);
-
- # standard non-profiling codepat
- $pob->event_read if $state & EPOLLIN && ! $pob->{closed};
- $pob->event_write if $state & EPOLLOUT && ! $pob->{closed};
- if ($state & (EPOLLERR|EPOLLHUP)) {
- $pob->event_err if $state & EPOLLERR && ! $pob->{closed};
- $pob->event_hup if $state & EPOLLHUP && ! $pob->{closed};
- }
+ event_step($DescriptorMap{$ev->[0]});
}
return unless PostEventLoop();
}
my ($fd, $state) = splice(@poll, 0, 2);
next unless $state;
- $pob = $DescriptorMap{$fd};
-
- $pob->event_read if $state & POLLIN && ! $pob->{closed};
- $pob->event_write if $state & POLLOUT && ! $pob->{closed};
- $pob->event_err if $state & POLLERR && ! $pob->{closed};
- $pob->event_hup if $state & POLLHUP && ! $pob->{closed};
+ event_step($DescriptorMap{$fd});
}
return unless PostEventLoop();
foreach my $kev (@ret) {
my ($fd, $filter, $flags, $fflags) = @$kev;
- my PublicInbox::DS $pob = $DescriptorMap{$fd};
-
- DebugLevel >= 1 && $class->DebugMsg("Event: fd=%d (%s), flags=%d \@ %s\n",
- $fd, ref($pob), $flags, time);
-
- $pob->event_read if $filter == IO::KQueue::EVFILT_READ() && !$pob->{closed};
- $pob->event_write if $filter == IO::KQueue::EVFILT_WRITE() && !$pob->{closed};
- if ($flags == IO::KQueue::EV_EOF() && !$pob->{closed}) {
- if ($fflags) {
- $pob->event_err;
- } else {
- $pob->event_hup;
- }
- }
+ event_step($DescriptorMap{$fd});
}
return unless PostEventLoop();
}
=head2 (VIRTUAL) C<< $obj->event_read() >>
Readable event handler. Concrete deriviatives of PublicInbox::DS should
-provide an implementation of this. The default implementation will die if
-called.
-
-=cut
-sub event_read { die "Base class event_read called for $_[0]\n"; }
-
-=head2 (VIRTUAL) C<< $obj->event_err() >>
-
-Error event handler. Concrete deriviatives of PublicInbox::DS should
-provide an implementation of this. The default implementation will die if
-called.
-
-=cut
-sub event_err { die "Base class event_err called for $_[0]\n"; }
-
-=head2 (VIRTUAL) C<< $obj->event_hup() >>
-
-'Hangup' event handler. Concrete deriviatives of PublicInbox::DS should
-provide an implementation of this. The default implementation will die if
-called.
+provide an implementation of this. The default implementation is a noop
+if called.
=cut
-sub event_hup { die "Base class event_hup called for $_[0]\n"; }
+sub event_read {} # noop
=head2 C<< $obj->event_write() >>