[[email protected]: Re: Event.pm]
[email protected] (Joshua N Pritikin) Thu, 9 May 2002 13:29:50 +0530
| Newsgroups | perl.loop |
|---|---|
| Message-ID | <[email protected]> |
----- Forwarded message from Scott Beck <[email protected]> ----- From: Scott Beck <[email protected]> To: Joshua N Pritikin <[email protected]> Subject: Re: Event.pm Organization: Gossamer Threads On Wed, 8 May 2002 10:46:07 +0530 Joshua N Pritikin <[email protected]> wrote: > On Tue, May 07, 2002 at 03:28:14PM -0700, Scott Beck wrote: > > I'm using your event module for a daemon that communicates through > > unix domain sockets. When I get to a point that I am no longer using a > > socket I call your->cancel() method on it's watcher. If I do this and > > do not close the socket my program starts using more and more CPU. If > > I close the socket Event.pm gives me a warning: > > Event: '?? gpanel_server:305' was unexpectedly closed at > > gpanel_server line 112 > > > > Is there something I am missing here? If you would like I can make a > > short example of my program and send it to you. I'm on slackware linux > > with perl 5.6.1. > > Yes, please send a short script to reproduce the problem. > > Thanks. Here you go. I tried to make it as short as possible. You will find the close() I was referring to on line 75 of server.pl. Let me know if you need anything else. Cheers, Scott -------------------- Gossamer Threads Inc. ---------------------- Scott Beck Email: [email protected] Lead Software Developer Phone: (604) 687-5804 http://www.gossamer-threads.com Fax: (604) 687-5806
server.pl
(application/x-perl, 2.6 KB)
#!/usr/bin/perl -w
# server.pl
use strict;
use warnings;
use constant SOCK => '/tmp/server.sock';
use Event qw/loop/;
use POSIX qw(fcntl_h errno_h :sys_wait_h);
use Socket;
use Symbol qw/gensym/;
$Event::DIED = sub {
Event::unloop_all();
};
my $Server = gensym;
my (%Out_Buffer, %In_Buffer);
main();
sub main {
socket($Server, PF_UNIX, SOCK_STREAM, 0)
or die "Could not create unix socket: $!";
# Turn off buffering
select((select($Server), $| = 1)[0]);
unlink SOCK;
bind($Server, sockaddr_un(SOCK))
or die "Could not bind to " . SOCK . "; Reason: $!";
listen($Server, SOMAXCONN) or die "listen: $!";
Event->io(
fd => $Server,
poll => 'r',
cb => \&handler_input
);
warn "Started [$$]\n";
loop;
}
sub handler_input {
my ($event) = @_;
my $watcher = $event->w;
my $client = $watcher->fd;
if ($client == $Server) {
my $client = gensym;
accept($client, $Server) or die "accept: $!";
Event->io(
fd => $client,
poll => 'r',
cb => \&handler_input
);
Event->io(
fd => $client,
poll => 'w',
cb => \&handler_output
);
}
else {
local $SIG{PIPE} = 'IGNORE';
my $data = '';
my $rv = sysread($client, $data, POSIX::BUFSIZ());
unless (defined($rv) and length($data)) {
delete $In_Buffer{$client};
delete $Out_Buffer{$client};
$watcher->cancel;
close $client; # If I remove this close I start spinning
return;
}
$In_Buffer{$client} .= $data;
if ($In_Buffer{$client} =~ s/(.*)\n//) {
warn "<-- $1\n";
if ($1 eq 'Hi') {
$Out_Buffer{$client} = "Why hello there\n";
}
}
}
}
sub handler_output {
my ($event) = @_;
my $watcher = $event->w;
my $client = $watcher->fd;
return unless exists $Out_Buffer{$client};
local $SIG{PIPE} = 'IGNORE';
warn "--> $Out_Buffer{$client}";
my $rv = syswrite($client, $Out_Buffer{$client});
unless (defined $rv) {
warn "We were suppose to be able to write but couldn't";
delete $In_Buffer{$client};
delete $Out_Buffer{$client};
$watcher->cancel;
return;
}
if ($rv == length($Out_Buffer{$client})) {
substr($Out_Buffer{$client}, 0, $rv) = '';
delete $Out_Buffer{$client} unless length $Out_Buffer{$client};
}
else {
delete $In_Buffer{$client};
delete $Out_Buffer{$client};
$watcher->cancel;
}
}
client.pl
(application/x-perl, 1.8 KB)
#!/usr/bin/perl -w
use strict;
use warnings;
use constant SOCK => '/tmp/server.sock';
use Event qw/loop unloop/;
use POSIX qw(fcntl_h errno_h :sys_wait_h);
use Socket;
use Symbol qw/gensym/;
my ($Out_Buffer, $In_Buffer);
main();
sub main {
my $client = gensym;
socket($client, PF_UNIX, SOCK_STREAM, 0)
or die "Could not create unix socket: $!";
connect($client, sockaddr_un(SOCK))
or die "Connect: $!";
# Turn off buffering
select((select($client), $| = 1)[0]);
$Out_Buffer = "Hi\n";
Event->io(
fd => $client,
poll => 'r',
cb => \&handler_input
);
Event->io(
fd => $client,
poll => 'w',
cb => \&handler_output
);
loop;
}
sub handler_input {
my ($event) = @_;
my $watcher = $event->w;
my $client = $watcher->fd;
local $SIG{PIPE} = 'IGNORE';
my $data = '';
my $rv = sysread($client, $data, POSIX::BUFSIZ());
unless (defined($rv) and length($data)) {
warn "Connectiong closed\n";
unloop;
}
$In_Buffer .= $data;
if ($In_Buffer =~ s/(.*)\n//) {
warn "<-- $1\n";
if ($1 eq "Why hello there") {
warn "All done\n";
close $client;
unloop;
}
}
}
sub handler_output {
my ($event) = @_;
my $watcher = $event->w;
my $client = $watcher->fd;
return unless length $Out_Buffer;
local $SIG{PIPE} = 'IGNORE';
warn "--> $Out_Buffer";
my $rv = syswrite($client, $Out_Buffer);
unless (defined $rv) {
warn "We were suppose to be able to write but couldn't";
close $client;
unloop;
}
if ($rv == length($Out_Buffer)) {
substr($Out_Buffer, 0, $rv) = '';
}
else {
warn "Problems: $!";
close $client;
unloop;
}
}