On Thu Nov 11 19:42:06 2010, PEVANS wrote:
Show quoted text> Find attached a patch for this particular part.
Uh.. I fail. _now_ attached.
--
Paul Evans
=== modified file 'KQueue.xs'
--- KQueue.xs 2010-11-11 19:12:54 +0000
+++ KQueue.xs 2010-11-11 21:34:07 +0000
@@ -56,11 +56,7 @@
int i;
PPCODE:
memset(&ke, 0, sizeof(struct kevent));
- if (udata)
- SvREFCNT_inc(udata);
- else
- udata = &PL_sv_undef;
- EV_SET(&ke, ident, filter, flags, fflags, data, udata);
+ EV_SET(&ke, ident, filter, flags, fflags, data, udata ? newSVsv(udata) : NULL);
i = kevent(kq, &ke, 1, NULL, 0, NULL);
if (i == -1) {
croak("set kevent failed: %s", strerror(errno));
@@ -107,7 +103,7 @@
av_push(array, newSViv(ke[i].flags));
av_push(array, newSViv(ke[i].fflags));
av_push(array, newSViv(ke[i].data));
- av_push(array, SvREFCNT_inc(ke[i].udata));
+ av_push(array, ke[i].udata ? newSVsv(ke[i].udata) : newSV(0));
PUSHs(sv_2mortal(newRV_noinc((SV*)array)));
}
=== modified file 'Makefile.PL'
--- Makefile.PL 2010-11-11 19:12:54 +0000
+++ Makefile.PL 2010-11-11 21:19:44 +0000
@@ -20,7 +20,10 @@
WriteMakefile(
VERSION_FROM => 'KQueue.pm',
NAME => 'IO::KQueue',
- PREREQ_PM => { },
+ PREREQ_PM => {
+ 'Test::Identity' => 0,
+ 'Test::Refcount' => 0,
+ },
ABSTRACT_FROM => 'KQueue.pm',
AUTHOR => 'Matt Sergeant <matt@sergeant.org>',
clean => {FILES => "tv.log"}
=== added file 't/10read.t'
--- t/10read.t 1970-01-01 00:00:00 +0000
+++ t/10read.t 2010-11-11 21:35:44 +0000
@@ -0,0 +1,52 @@
+#!/usr/bin/perl -w
+
+use strict;
+use warnings;
+
+use Test::More tests => 11;
+use Test::Identity;
+use Test::Refcount;
+
+use IO::KQueue;
+
+use IO::Handle;
+
+my $kq = IO::KQueue->new;
+
+pipe( my $readh, my $writeh ) or die "Cannot pipe() - $!";
+
+my $userdata = [ "user data" ];
+is_oneref( $userdata, '$userdata has one reference initially' );
+
+$kq->EV_SET( fileno($readh), EVFILT_READ, EV_ADD, 0, 0, $userdata );
+
+is_refcount( $userdata, 2, '$userdata has two references after ->EV_SET(EV_ADD)' );
+
+my @events;
+@events = $kq->kevent( 0 );
+
+is( scalar @events, 0, 'No events initially' );
+
+$writeh->syswrite( "Hello\n" );
+
+@events = $kq->kevent( 1 );
+
+is( scalar @events, 1, 'One event received' );
+
+my $ev = shift @events;
+is( $ev->[KQ_IDENT], fileno $readh, '$ev->[KQ_IDENT]' );
+is( $ev->[KQ_FILTER], EVFILT_READ, '$ev->[KQ_FILTER]' );
+is( $ev->[KQ_FLAGS], 0, '$ev->[KQ_FLAGS]' );
+is( $ev->[KQ_DATA], 6, '$ev->[KQ_DATA]' );
+identical( $ev->[KQ_UDATA], $userdata, '$ev->[KQ_UDATA]' );
+
+is_refcount( $userdata, 3, '$userdata has three references after ->kevent' );
+
+# Clear it
+$readh->sysread( my $buffer, 8192 );
+
+undef $ev;
+
+$kq->EV_SET( fileno($readh), EVFILT_READ, EV_DELETE );
+
+is_oneref( $userdata, '$userdata has one reference finally' );
=== added file 't/11signal.t'
--- t/11signal.t 1970-01-01 00:00:00 +0000
+++ t/11signal.t 2010-11-11 21:35:50 +0000
@@ -0,0 +1,59 @@
+#!/usr/bin/perl -w
+
+use strict;
+use warnings;
+
+use Test::More tests => 13;
+use Test::Identity;
+use Test::Refcount;
+
+use IO::KQueue;
+
+use POSIX qw( SIGUSR1 );
+
+my $kq = IO::KQueue->new;
+
+$SIG{USR1} = "IGNORE";
+
+my $userdata = [ "user data" ];
+is_oneref( $userdata, '$userdata has one reference initially' );
+
+$kq->EV_SET( SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, $userdata );
+
+is_refcount( $userdata, 2, '$userdata has two references after ->EV_SET(EV_ADD)' );
+
+my @events;
+@events = $kq->kevent( 0 );
+
+is( scalar @events, 0, 'No events initially' );
+
+kill USR1 => $$;
+
+@events = $kq->kevent( 1 );
+
+is( scalar @events, 1, 'One event received' );
+
+my $ev = shift @events;
+is( $ev->[KQ_IDENT], SIGUSR1, '$ev->[KQ_IDENT]' );
+is( $ev->[KQ_FILTER], EVFILT_SIGNAL, '$ev->[KQ_FILTER]' );
+is( $ev->[KQ_FLAGS], EV_CLEAR, '$ev->[KQ_FLAGS]' );
+is( $ev->[KQ_DATA], 1, '$ev->[KQ_DATA]' );
+identical( $ev->[KQ_UDATA], $userdata, '$ev->[KQ_UDATA]' );
+
+kill USR1 => $$;
+kill USR1 => $$;
+
+@events = $kq->kevent( 1 );
+
+is( scalar @events, 1, 'One event received after two kill()s' );
+
+$ev = shift @events;
+is( $ev->[KQ_DATA], 2, '$ev->[KQ_DATA] == 2' );
+
+is_refcount( $userdata, 3, '$userdata has three references after ->kevent' );
+
+undef $ev;
+
+$kq->EV_SET( SIGUSR1, EVFILT_SIGNAL, EV_DELETE );
+
+is_oneref( $userdata, '$userdata has one reference finally' );
=== added file 't/12timer.t'
--- t/12timer.t 1970-01-01 00:00:00 +0000
+++ t/12timer.t 2010-11-11 21:36:11 +0000
@@ -0,0 +1,43 @@
+#!/usr/bin/perl -w
+
+use strict;
+use warnings;
+
+use Test::More tests => 11;
+use Test::Identity;
+use Test::Refcount;
+
+use IO::KQueue;
+
+my $kq = IO::KQueue->new;
+
+my $userdata = [ "user data" ];
+is_oneref( $userdata, '$userdata has one reference initially' );
+
+$kq->EV_SET( 1, EVFILT_TIMER, EV_ADD, 0, 50, $userdata );
+
+is_refcount( $userdata, 2, '$userdata has two references after ->EV_SET(EV_ADD)' );
+
+my @events;
+@events = $kq->kevent( 0 );
+
+is( scalar @events, 0, 'No events initially' );
+
+@events = $kq->kevent( 100 );
+
+is( scalar @events, 1, 'One event received' );
+
+my $ev = shift @events;
+is( $ev->[KQ_IDENT], 1, '$ev->[KQ_IDENT]' );
+is( $ev->[KQ_FILTER], EVFILT_TIMER, '$ev->[KQ_FILTER]' );
+is( $ev->[KQ_FLAGS], EV_CLEAR, '$ev->[KQ_FLAGS]' );
+is( $ev->[KQ_DATA], 1, '$ev->[KQ_DATA]' );
+identical( $ev->[KQ_UDATA], $userdata, '$ev->[KQ_UDATA]' );
+
+is_refcount( $userdata, 3, '$userdata has three references after ->kevent' );
+
+undef $ev;
+
+$kq->EV_SET( 1, EVFILT_TIMER, EV_DELETE );
+
+is_oneref( $userdata, '$userdata has one reference finally' );