El objeto Event::Event pasado al callback/manejador almacena información similar a la de los objetos watcher, pero a diferencia de estos sus atributos no pueden ser modificados.
Aunque la mayoría de los objetos evento pertenecen a la clase Event::Event algunos pertencen a una subclase:
pp2@nereida:~/src/perl/Event$ perl -wde 0 main::(-e:1): 0 DB<1> use Event DB<2> Event->io(fd => \*STDIN, cb => sub { print ref($_[0])."\n"; Event::unloop }) DB<3> Event::loop hola Event::Event::Io DB<4> hola DB<5> Event->timer(at => time()+1, cb => sub { print ref($_[0])."\n"; Event::unloop }) DB<6> Event::loop Event::Event DB<7> Event->idle(cb => sub { print ref($_[0])."\n"; Event::unloop }) DB<8> Event::loop Event::Event
$event->w
:
El vigilante que detectó este objeto.
Una construcción típica de un callback en Event
es:
sub callback { my $event = shift; my $watcher = $event->w; ... }
$event->got
:
Disponible si el vigilante tiene el atributo poll
. Describe el
evento en formato poll. El formato poll usa una de las letras rwet
para indicar
lectura, escritura, excepción o timeout. También es posible usar una de las constantes
disponibles via
use Event::Watcher qw{R W E T};Estos dos ejemplos indican que el vigilante esta interesado en la lectura:
$w->poll($w->poll.'r'); $w->poll($w->poll | R);
Véase el siguiente ejemplo:
pp2@nereida:~/src/perl/Event/demo$ cat -n ./echo.pl 1 #!/usr/bin/perl 2 use warnings; 3 use strict; 4 5 $| = 1; 6 use Event qw(time); 7 8 print "This demo echoes whatever you type. If you don't type anything 9 for as long as 2.5 seconds then it will complain. Enter an empty line 10 to exit. 11 12 "; 13 14 my $recent = time; 15 Event->io(fd => \*STDIN, 16 timeout => 2.5, 17 poll => "rte", 18 repeat => 1, 19 cb => sub { 20 my $e = shift; 21 my $got = $e->got; 22 23 print scalar(localtime), " "; 24 if ($got eq "r") { 25 my $buf; 26 sysread(STDIN, $buf, 80); 27 chop $buf; 28 my $len = length($buf); 29 Event::unloop if !$len; 30 print "read[$len]:$buf:\n"; 31 $recent = time; 32 } elsif ($got eq "t") { 33 warn "Got: $got. Nothing for ".(time - $recent)." seconds\n"; 34 } 35 elsif ($got eq 'e') { 36 warn "got: $got. Exception raised!\n"; 37 exit; 38 } 39 } 40 ); 41 42 Event::loop();Al ejecutar obtenemos:
pp2@nereida:~/src/perl/Event/demo$ ./echo.pl This demo echoes whatever you type. If you don't type anything for as long as 2.5 seconds then it will complain. Enter an empty line to exit. Mon Apr 28 10:05:57 2008 Got: t. Nothing for 2.50072288513184 seconds Mon Apr 28 10:05:59 2008 Got: t. Nothing for 5.00051188468933 seconds Hola!Mon Apr 28 10:06:02 2008 Got: t. Nothing for 7.50045204162598 seconds Mon Apr 28 10:06:02 2008 read[5]:Hola!: Mon Apr 28 10:06:04 2008 read[0]::
$event->hits
:
Cuando las señales llegan en rápida sucesión pueden ser agrupadas en un único evento. El número de señales agrupadas se puede consultar en este atributo.
$event->prio
:
La prioridad del vigilante en el momento de generación del evento. Cuidado: la prioridad del vigilante puede haber cambiado desde que este evento fué generado
El objeto Event::Event congela el estado del evento en el momento de entrar en la cola. El vigilante continúa trabajando y otras partes del programa pueden haberlo modificado desde el momento en que el evento entró en la cola hasta el momento en el que se ejecuta el callback/manejador (que puede ser un tiempo no despreciable). Incluso podría ocurrir que el watcher haya sido cancelado en cuyo caso cualquier intento de modificarlo provocaría una excepción. Por ello es conveniente comprobar el estado del watcher antes de modificarlo (dentro de un callback):
sub callback { my $event = shift; my $w = $event->w; ... $w->prio($w->prio-1) unless $w->is_cancelled; ... }
Recuerde que hay un único proceso para el reconocimiento y manejo de eventos. Mientras una callback esta ejecutándose el bucle, los vigilantes y los restantes manejadores permanecen bloqueados. Por ello es necesario que una callback retorne con rapidez. Si no es el caso siempre es posible:
Event
.
Event->sweep Event->sweep($max_prio)
Este método encola todos los eventos pendientes (con prioridad $w->prio < $max_prio
.
La menor prioridad es 0)
y los procesa. Por defecto los eventos idle
no son procesados.
Aunque sweep
ignora los eventos idle
, no ignora
los vigilantes idle
. Si se quiere que ignore a estos también se debe
poner el atributo max
de éstos a undef
o bien llamar
a su método stop
.