r68570 - in /trunk/libio-async-loop-epoll-perl: Changes LICENSE META.yml debian/changelog lib/IO/Async/Loop/Epoll.pm

jawnsy-guest at users.alioth.debian.org jawnsy-guest at users.alioth.debian.org
Mon Feb 14 00:59:29 UTC 2011


Author: jawnsy-guest
Date: Mon Feb 14 00:59:21 2011
New Revision: 68570

URL: http://svn.debian.org/wsvn/pkg-perl/?sc=1&rev=68570
Log:
Integrate new upstream release

Modified:
    trunk/libio-async-loop-epoll-perl/Changes
    trunk/libio-async-loop-epoll-perl/LICENSE
    trunk/libio-async-loop-epoll-perl/META.yml
    trunk/libio-async-loop-epoll-perl/debian/changelog
    trunk/libio-async-loop-epoll-perl/lib/IO/Async/Loop/Epoll.pm

Modified: trunk/libio-async-loop-epoll-perl/Changes
URL: http://svn.debian.org/wsvn/pkg-perl/trunk/libio-async-loop-epoll-perl/Changes?rev=68570&op=diff
==============================================================================
--- trunk/libio-async-loop-epoll-perl/Changes (original)
+++ trunk/libio-async-loop-epoll-perl/Changes Mon Feb 14 00:59:21 2011
@@ -1,4 +1,14 @@
 Revision history for IO-Async-Loop-Epoll
+
+0.11    CHANGES:
+         * Dynamically scale epoll_pwait() maxevents parameter to avoid
+           stalling higher-numbered FDs during high load
+         * Emulate non-epoll'able filehandles (e.g. regular files) as always
+           read/write-ready
+
+0.10    BUGFIXES:
+         * Try to workaround perl blobk/unblock signals bug by using an unsafe
+           POSIX::SigAction handler
 
 0.09    CHANGES:
          * Updated API version for IO::Async 0.33

Modified: trunk/libio-async-loop-epoll-perl/LICENSE
URL: http://svn.debian.org/wsvn/pkg-perl/trunk/libio-async-loop-epoll-perl/LICENSE?rev=68570&op=diff
==============================================================================
--- trunk/libio-async-loop-epoll-perl/LICENSE (original)
+++ trunk/libio-async-loop-epoll-perl/LICENSE Mon Feb 14 00:59:21 2011
@@ -1,4 +1,4 @@
-This software is copyright (c) 2010 by Paul Evans <leonerd at leonerd.org.uk>.
+This software is copyright (c) 2011 by Paul Evans <leonerd at leonerd.org.uk>.
 
 This is free software; you can redistribute it and/or modify it under
 the same terms as the Perl 5 programming language system itself.
@@ -12,7 +12,7 @@
 
 --- The GNU General Public License, Version 1, February 1989 ---
 
-This software is Copyright (c) 2010 by Paul Evans <leonerd at leonerd.org.uk>.
+This software is Copyright (c) 2011 by Paul Evans <leonerd at leonerd.org.uk>.
 
 This is free software, licensed under:
 
@@ -270,7 +270,7 @@
 
 --- The Artistic License 1.0 ---
 
-This software is Copyright (c) 2010 by Paul Evans <leonerd at leonerd.org.uk>.
+This software is Copyright (c) 2011 by Paul Evans <leonerd at leonerd.org.uk>.
 
 This is free software, licensed under:
 

Modified: trunk/libio-async-loop-epoll-perl/META.yml
URL: http://svn.debian.org/wsvn/pkg-perl/trunk/libio-async-loop-epoll-perl/META.yml?rev=68570&op=diff
==============================================================================
--- trunk/libio-async-loop-epoll-perl/META.yml (original)
+++ trunk/libio-async-loop-epoll-perl/META.yml Mon Feb 14 00:59:21 2011
@@ -16,10 +16,10 @@
 provides:
   IO::Async::Loop::Epoll:
     file: lib/IO/Async/Loop/Epoll.pm
-    version: 0.09
+    version: 0.11
 requires:
   IO::Async: 0.24
   IO::Epoll: 0.02
 resources:
   license: http://dev.perl.org/licenses/
-version: 0.09
+version: 0.11

Modified: trunk/libio-async-loop-epoll-perl/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-perl/trunk/libio-async-loop-epoll-perl/debian/changelog?rev=68570&op=diff
==============================================================================
--- trunk/libio-async-loop-epoll-perl/debian/changelog (original)
+++ trunk/libio-async-loop-epoll-perl/debian/changelog Mon Feb 14 00:59:21 2011
@@ -1,4 +1,4 @@
-libio-async-loop-epoll-perl (0.09-1) UNRELEASED; urgency=low
+libio-async-loop-epoll-perl (0.11-1) UNRELEASED; urgency=low
 
   WAITS-FOR: libio-async-perl 0.33
 
@@ -6,7 +6,7 @@
     + Update for the new IO::Async 0.33 API
   * Refresh copyright information
 
- -- Jonathan Yu <jawnsy at cpan.org>  Fri, 24 Dec 2010 15:55:22 -0500
+ -- Jonathan Yu <jawnsy at cpan.org>  Sun, 13 Feb 2011 20:12:31 -0500
 
 libio-async-loop-epoll-perl (0.08-1) unstable; urgency=low
 

Modified: trunk/libio-async-loop-epoll-perl/lib/IO/Async/Loop/Epoll.pm
URL: http://svn.debian.org/wsvn/pkg-perl/trunk/libio-async-loop-epoll-perl/lib/IO/Async/Loop/Epoll.pm?rev=68570&op=diff
==============================================================================
--- trunk/libio-async-loop-epoll-perl/lib/IO/Async/Loop/Epoll.pm (original)
+++ trunk/libio-async-loop-epoll-perl/lib/IO/Async/Loop/Epoll.pm Mon Feb 14 00:59:21 2011
@@ -1,15 +1,16 @@
 #  You may distribute under the terms of either the GNU General Public License
 #  or the Artistic License (the same terms as Perl itself)
 #
-#  (C) Paul Evans, 2008-2010 -- leonerd at leonerd.org.uk
+#  (C) Paul Evans, 2008-2011 -- leonerd at leonerd.org.uk
 
 package IO::Async::Loop::Epoll;
 
 use strict;
 use warnings;
 
-our $VERSION = '0.09';
+our $VERSION = '0.11';
 use constant API_VERSION => '0.33';
+use constant _CAN_ON_HANGUP => 1;
 
 use base qw( IO::Async::Loop );
 
@@ -21,7 +22,7 @@
    EPOLLIN EPOLLOUT EPOLLHUP EPOLLERR
 );
 
-use POSIX qw( EINTR SIG_BLOCK SIG_UNBLOCK sigprocmask );
+use POSIX qw( EINTR EPERM SIG_BLOCK SIG_UNBLOCK sigprocmask sigaction );
 
 =head1 NAME
 
@@ -99,8 +100,11 @@
 
    $self->{epoll} = $epoll;
    $self->{sigmask} = POSIX::SigSet->new();
-
-   $self->{restore_SIG} = {};
+   $self->{maxevents} = 8;
+
+   $self->{fakeevents} = {};
+
+   $self->{signals} = {};
 
    return $self;
 }
@@ -117,7 +121,7 @@
 {
    my $self = shift;
 
-   foreach my $signal ( keys %{ $self->{restore_SIG} } ) {
+   foreach my $signal ( keys %{ $self->{signals} } ) {
       $self->unwatch_signal( $signal );
    }
 }
@@ -141,16 +145,18 @@
 
    my $msec = defined $timeout ? $timeout * 1000 : -1;
 
-   my $ret = epoll_pwait( $self->{epoll}, 20, $msec, $self->{sigmask} );
-
-   return 0 if !$ret and $! == EINTR; # Caught signal
-   return undef if !$ret;             # Some other error
+   my $ret = epoll_pwait( $self->{epoll}, $self->{maxevents}, $msec, $self->{sigmask} );
+
+   return undef if !$ret and $! != EINTR;
 
    my $count = 0;
 
    my $iowatches = $self->{iowatches};
 
-   foreach my $ev ( @$ret ) {
+   my $fakeevents = $self->{fakeevents};
+   my @fakeevents = map { [ $_ => $fakeevents->{$_} ] } keys %$fakeevents;
+
+   foreach my $ev ( @$ret, @fakeevents ) {
       my ( $fd, $bits ) = @$ev;
 
       my $watch = $iowatches->{$fd};
@@ -164,14 +170,31 @@
          $watch->[2]->() if $watch->[2];
          $count++;
       }
+
+      if( $bits & EPOLLHUP ) {
+         $watch->[3]->() if $watch->[3];
+         $count++;
+      }
+   }
+
+   my $signals = $self->{signals};
+   foreach my $sigslot ( values %$signals ) {
+      if( $sigslot->[1] ) {
+         $sigslot->[0]->();
+         $sigslot->[1] = 0;
+         $count++;
+      }
    }
 
    $count += $self->_manage_queues;
 
+   # If we entirely filled the event buffer this time, we may have missed some
+   # Lets get a bigger buffer next time
+   $self->{maxevents} *= 2 if @$ret == $self->{maxevents};
+
    return $count;
 }
 
-# override
 sub watch_io
 {
    my $self = shift;
@@ -189,17 +212,36 @@
    my $mask = $curmask;
    $params{on_read_ready}  and $mask |= EPOLLIN;
    $params{on_write_ready} and $mask |= EPOLLOUT;
+   $params{on_hangup}      and $mask |= EPOLLHUP;
+
+   my $fakeevents = $self->{fakeevents};
 
    if( !$curmask ) {
-      epoll_ctl( $epoll, EPOLL_CTL_ADD, $fd, $mask ) == 0
-         or carp "Cannot EPOLL_CTL_ADD($fd,$mask) - $!";
+      if( epoll_ctl( $epoll, EPOLL_CTL_ADD, $fd, $mask ) == 0 ) {
+         # All OK
+      }
+      elsif( $! == EPERM ) {
+         # The filehandle isn't epoll'able. This means kernel thinks it should
+         # always be ready.
+         $fakeevents->{$fd} = $mask;
+      }
+      else {
+         croak "Cannot EPOLL_CTL_ADD($fd,$mask) - $!";
+      }
+
+      $self->{masks}->{$fd} = $mask;
    }
    elsif( $mask != $curmask ) {
-      epoll_ctl( $epoll, EPOLL_CTL_MOD, $fd, $mask ) == 0
-         or carp "Cannot EPOLL_CTL_MOD($fd,$mask) - $!";
-   }
-
-   $self->{masks}->{$fd} = $mask;
+      if( exists $fakeevents->{$fd} ) {
+         $fakeevents->{$fd} = $mask;
+      }
+      else {
+         epoll_ctl( $epoll, EPOLL_CTL_MOD, $fd, $mask ) == 0
+            or croak "Cannot EPOLL_CTL_MOD($fd,$mask) - $!";
+      }
+
+      $self->{masks}->{$fd} = $mask;
+   }
 }
 
 sub unwatch_io
@@ -219,15 +261,30 @@
    my $mask = $curmask;
    $params{on_read_ready}  and $mask &= ~EPOLLIN;
    $params{on_write_ready} and $mask &= ~EPOLLOUT;
+   $params{on_hangup}      and $mask &= ~EPOLLHUP;
+
+   my $fakeevents = $self->{fakeevents};
 
    if( $mask ) {
-      epoll_ctl( $epoll, EPOLL_CTL_MOD, $fd, $mask ) == 0
-         or carp "Cannot EPOLL_CTL_MOD($fd,$mask) - $!";
+      if( exists $fakeevents->{$fd} ) {
+         $fakeevents->{$fd} = $mask;
+      }
+      else {
+         epoll_ctl( $epoll, EPOLL_CTL_MOD, $fd, $mask ) == 0
+            or croak "Cannot EPOLL_CTL_MOD($fd,$mask) - $!";
+      }
+
       $self->{masks}->{$fd} = $mask;
    }
    else {
-      epoll_ctl( $epoll, EPOLL_CTL_DEL, $fd, 0 ) == 0
-         or carp "Cannot EPOLL_CTL_DEL($fd) - $!";
+      if( exists $fakeevents->{$fd} ) {
+         delete $fakeevents->{$fd};
+      }
+      else {
+         epoll_ctl( $epoll, EPOLL_CTL_DEL, $fd, 0 ) == 0
+            or croak "Cannot EPOLL_CTL_DEL($fd) - $!";
+      }
+
       delete $self->{masks}->{$fd};
    }
 }
@@ -240,13 +297,21 @@
 
    exists $SIG{$signal} or croak "Unrecognised signal name $signal";
 
-   $self->{restore_SIG}->{$signal} = $SIG{$signal};
+   # We cannot simply set $SIG{$signal} = $code here, because of perl bug
+   #   http://rt.perl.org/rt3/Ticket/Display.html?id=82040
+   # Instead, we'll store a tiny piece of code that just sets a flag, and
+   # check the flags on return from the epoll_pwait call.
+
+   $self->{signals}{$signal} = [ $code, 0, $SIG{$signal} ];
+   my $pending = \$self->{signals}{$signal}[1];
 
    my $signum = $self->signame2num( $signal );
-
    sigprocmask( SIG_BLOCK, POSIX::SigSet->new( $signum ) );
 
-   $SIG{$signal} = $code;
+   # Note this is an unsafe signal handler, and as such it should do as little
+   # as possible.
+   my $sigaction = POSIX::SigAction->new( sub { $$pending = 1 } );
+   sigaction( $signum, $sigaction ) or croak "Unable to sigaction - $!";
 }
 
 # override
@@ -259,9 +324,9 @@
 
    # When we saved the original value, we might have got an undef. But %SIG
    # doesn't like having undef assigned back in, so we need to translate
-   $SIG{$signal} = $self->{restore_SIG}->{$signal} || 'DEFAULT';
-
-   delete $self->{restore_SIG}->{$signal};
+   $SIG{$signal} = $self->{signals}{$signal}[2] || 'DEFAULT';
+
+   delete $self->{signals}{$signal};
    
    my $signum = $self->signame2num( $signal );
 




More information about the Pkg-perl-cvs-commits mailing list