]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/DS.pm
ds: move requeue_once
[public-inbox.git] / lib / PublicInbox / DS.pm
index debb777a27e88ca675f703b396b1482138046b02..f0181b5461cfc4111574af2991d3522a57aba174 100644 (file)
@@ -37,9 +37,7 @@ our @EXPORT_OK = qw(now msg_more dwaitpid add_timer add_uniq_timer);
 my %Stack;
 my $nextq; # queue for next_tick
 my $wait_pids; # list of [ pid, callback, callback_arg ]
-my $EXPMAP; # fd -> idle_time
-our $EXPTIME = 180; # 3 minutes
-my ($reap_armed);
+my $reap_armed;
 my $ToClose; # sockets to close when event loop is done
 our (
      %DescriptorMap,             # fd (num) -> PublicInbox::DS object
@@ -76,7 +74,6 @@ sub Reset {
                # we may be iterating inside one of these on our stack
                my @q = delete @Stack{keys %Stack};
                for my $q (@q) { @$q = () }
-               $EXPMAP = undef;
                $wait_pids = $nextq = $ToClose = undef;
                $ep_io = undef; # closes real $Epoll FD
                $Epoll = undef; # may call DSKQXS::DESTROY
@@ -251,9 +248,6 @@ sub PostEventLoop () {
                $ToClose = undef; # will be autovivified on push
                @$close_now = map { fileno($_) } @$close_now;
 
-               # order matters, destroy expiry times, first:
-               delete @$EXPMAP{@$close_now};
-
                # ->DESTROY methods may populate ToClose
                delete @DescriptorMap{@$close_now};
        }
@@ -353,6 +347,24 @@ retry:
     $DescriptorMap{$fd} = $self;
 }
 
+# for IMAP, NNTP, and POP3 which greet clients upon connect
+sub greet {
+       my ($self, $sock) = @_;
+       my $ev = EPOLLIN;
+       my $wbuf;
+       if ($sock->can('accept_SSL') && !$sock->accept_SSL) {
+               return CORE::close($sock) if $! != EAGAIN;
+               $ev = PublicInbox::TLS::epollbit() or return CORE::close($sock);
+               $wbuf = [ \&accept_tls_step, $self->can('do_greet')];
+       }
+       new($self, $sock, $ev | EPOLLONESHOT);
+       if ($wbuf) {
+               $self->{wbuf} = $wbuf;
+       } else {
+               $self->do_greet;
+       }
+       $self;
+}
 
 #####################################################################
 ### I N S T A N C E   M E T H O D S
@@ -494,16 +506,15 @@ sub drop {
     $self->close;
 }
 
-# n.b.: use ->write/->read for this buffer to allow compatibility with
-# PerlIO::mmap or PerlIO::scalar if needed
 sub tmpio ($$$) {
        my ($self, $bref, $off) = @_;
        my $fh = tmpfile('wbuf', $self->{sock}, O_APPEND) or
                return drop($self, "tmpfile $!");
        $fh->autoflush(1);
        my $len = length($$bref) - $off;
-       print $fh substr($$bref, $off, $len) or
+       my $n = syswrite($fh, $$bref, $len, $off) //
                return drop($self, "write ($len): $!");
+       $n == $len or return drop($self, "wrote $n < $len bytes");
        [ $fh, 0 ] # [1] = offset, [2] = length, not set by us
 }
 
@@ -637,6 +648,22 @@ sub shutdn ($) {
     }
 }
 
+sub zflush {} # overridden by NNTPdeflate and IMAPdeflate
+
+sub requeue_once {
+       my ($self) = @_;
+       # COMPRESS users all share the same DEFLATE context.
+       # Flush it here to ensure clients don't see
+       # each other's data
+       $self->zflush;
+
+       # no recursion, schedule another call ASAP,
+       # but only after all pending writes are done.
+       # autovivify wbuf.  wbuf may be populated by $cb,
+       # no need to rearm if so: (push returns new size of array)
+       requeue($self) if push(@{$self->{wbuf}}, $self->can('long_step')) == 1;
+}
+
 sub dwaitpid ($;$$) {
        my ($pid, $cb, $arg) = @_;
        if ($in_loop) {
@@ -656,35 +683,6 @@ sub dwaitpid ($;$$) {
        }
 }
 
-sub expire_old () {
-       my $cur = $EXPMAP or return;
-       $EXPMAP = undef;
-       my $old = now() - $EXPTIME;
-       while (my ($fd, $idle_at) = each %$cur) {
-               if ($idle_at < $old) {
-                       my $ds_obj = $DescriptorMap{$fd};
-                       $EXPMAP->{$fd} = $idle_at if !$ds_obj->shutdn;
-               } else {
-                       $EXPMAP->{$fd} = $idle_at;
-               }
-       }
-       add_uniq_timer('expire', 60, \&expire_old) if $EXPMAP;
-}
-
-sub update_idle_time {
-       my ($self) = @_;
-       my $sock = $self->{sock} or return;
-       $EXPMAP->{fileno($sock)} = now();
-       add_uniq_timer('expire', 60, \&expire_old);
-}
-
-sub not_idle_long {
-       my ($self, $now) = @_;
-       my $sock = $self->{sock} or return;
-       my $idle_at = $EXPMAP->{fileno($sock)} or return;
-       ($idle_at + $EXPTIME) > $now;
-}
-
 1;
 
 =head1 AUTHORS (Danga::Socket)