Gestión de los Objetos Watchers

Constructores de Vigilantes y Ámbito

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;

sleep y Event::sleep

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$

Accediendo a Vigilantes Anónimos desde un Callback

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;
  ...

}



Subsecciones
Casiano Rodríguez León
2012-02-29