Lo habitual cuando se llama a un constructor es guardar el objeto retornado por el constructor en una variable:
{
my $w = Event->signal( signal => 'INT', cb => sub { warn $_[0]->hits,"\n"; });
}
Cuando se usa Event es habitual ver código - como en el siguiente ejemplo - en el que no se almacena el objeto retornado:
1 use strict;
2 use warnings;
3
4 use Event;
5 Event->signal(
6 signal => 'INT',
7 cb => sub {
8 warn "Detected ",$_[0]->hits," SIGINT events\n";
9 warn "Sleeping now\n";
10
11 Event::sleep(10);
12 warn "Slept.\n";
13 }
14 );
15
16 Event::loop;
En general un callback se ejecuta en exclusiva. Existe una excepción a la regla:
Si una señal llega mientras el callback esta ejecutando sleep o select
para esperar, el callback se verá interrumpido por la señal. Si se quiere un
sleep no interrumpible deberemos usar Event::sleep .
Observe la siguiente variante del progframa anterior:
pp2@nereida:~/src/perl/Event$ cat -n sleepsignalwatcher.pl
1 use strict;
2 use warnings;
3
4 use Event;
5
6 my $count = 0;
7 Event->signal(
8 signal => 'INT',
9 cb => sub {
10 warn "Detected ",$_[0]->hits," SIGINT events\n";
11 $count += $_[0]->hits;
12 warn "Sleeping now\n";
13
14 sleep(10);
15
16 Event::unloop if $count > 5;
17 warn "Slept.\n";
18 }
19 );
20
21 Event::loop;
Cuando se ejecutan los códigos anteriores se producen salidas como estas:
Con Event::sleep |
Con sleep |
pp2@nereida:~/src/perl/Event$ perl signalwatcher.pl Detected 1 SIGINT events Sleeping now Slept. Detected 17 SIGINT events Sleeping now Slept. |
pp2@nereida:~/src/perl/Event$ perl sleepsignalwatcher.pl Detected 1 SIGINT events Sleeping now Slept. Detected 1 SIGINT events Sleeping now Slept. Detected 1 SIGINT events Sleeping now Slept. Detected 1 SIGINT events Sleeping now Slept. Detected 1 SIGINT events Sleeping now Slept. Detected 1 SIGINT events Sleeping now Slept. pp2@nereida:~/src/perl/Event$ |
La gestión que hace Event de los watchers resulta en un aumento del contador de referencias de manera que el objeto watcher no es destruido al finalizar el ámbito:
{
Event->signal( signal => 'INT', cb => sub { warn $_[0]->hits,"\n"; });
}
El nuevo vigilante permanece después de abandonado el
ámbito léxico. ¿Cómo accederlo entonces?. La respuesta es que se
dispone de los siguientes métodos de la clase Event para
obtener los watchers:
all_watchers |
Lista de los watchers registrados |
all_running |
Lista de los watchers con callbacks en ejecución |
all_idle |
Lista de los watchers ociosos, listos para ser servidos pero retrasados por eventos mas priorizados |
Además el objeto evento pasado al callback dispone de un método w
que permite acceder al watcher que le detectó.
Así pues una construcción típica
en Event es:
sub callback {
my $event = shift;
my $watcher = $event->w;
...
}
