Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 122 lines (112 sloc) 4.706 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
#!/usr/bin/perl -w
# $Id$

# This program tests signals. It tests OS signals (such as SIGINT),
# soft signals to sessions, and soft signals to kernels. Soft
# signals, by the way, are ones generated with the Kernel::signal()
# function. They don't involve the underlying OS, and so can send
# arbitrarily named signals.

use strict;
use lib '../lib';
use POE;

#==============================================================================
# This is a pathological example of an inline session. It defines the
# subs for each event handler within the POE::Session constructor's
# parameters. It's not bad for quick hacks.
#
# Anyway, this session registers handlers for SIGINT and two
# fictitious signals (SIGFOO and SIGQUUX). The session then starts an
# alarm loop that signals FOO to itself once a second.

POE::Session->create(
  inline_states => {
                                        ### _start the session
    '_start' => sub{
      my $kernel = $_[KERNEL];
                                        # register signal handlers
      $kernel->sig('INT', 'signal handler');
      $kernel->sig('FOO', 'signal handler');
      $kernel->sig('QUUX', 'signal handler');
                                        # hello, world!
      print "First session started... send SIGINT to stop.\n";
                                        # start the alarm loop
      $kernel->delay('set an alarm', 1);
    },
                                        ### _stop the session
    '_stop' => sub {
      print "First session stopped.\n";
    },
                                        ### alarm handler
    'set an alarm' => sub {
      my ($kernel, $session) = @_[KERNEL, SESSION];
      print "First session's alarm rang. Sending SIGFOO to itself...\n";
                                        # send a signal to itself
      $kernel->signal($session, 'FOO');
                                        # reset the alarm for 1s from now
      $kernel->delay('set an alarm', 1);
    },
                                        ### signal handler
    'signal handler' => sub {
      my ($kernel, $signal_name) = @_[KERNEL, ARG0];
      print "First session caught SIG$signal_name\n";
      print(
        "First session's pending alarms: ",
         join(':', map { "\"$_\"" } $kernel->queue_peek_alarms()), "\n"
      );
                                        # stop pending alarm on SIGINT
      if ($signal_name eq 'INT') {
        print "First session stopping...\n";
        $kernel->delay('set an alarm');
      }
    },
  }
);

#==============================================================================
# This is another pathological inline session. This one registers
# handlers for SIGINT and two fictitious signals (SIGBAZ and SIGQUUX).
# The session then starts an alarm loop that signals QUUX to the
# kernel twice a second. This propagates SIGQUUX to every session.

POE::Session->create(
  inline_states => {
                                        ### _start the session
    '_start' => sub {
      my $kernel = $_[KERNEL];
                                        # register signal handlers
      $kernel->sig('INT', 'signal handler');
      $kernel->sig('BAZ', 'signal handler');
      $kernel->sig('QUUX', 'signal handler');
                                        # hello, world!
      print "Second session started... send SIGINT to stop.\n";
                                        # start the alarm loop
      $kernel->delay('set an alarm', 0.5);
    },
                                        ### _stop the session
    '_stop' => sub {
      print "Second session stopped.\n";
    },
                                        ### alarm handler
    'set an alarm' => sub {
      my $kernel = $_[KERNEL];
      print "Second session's alarm rang. Sending SIGQUUX to kernel...\n";
                                        # signal the kernel
      $kernel->signal($kernel, 'QUUX');
                                        # reset the alarm for 1/2s from now
      $kernel->delay('set an alarm', 0.5);
    },
                                        ### signal handler
    'signal handler' => sub {
      my ($kernel, $signal_name) = @_[KERNEL, ARG0];
      print "Second session caught SIG$signal_name\n";
      print( "Second session's pending alarms: ",
             join(':', $kernel->queue_peek_alarms()), "\n"
           );
                                        # stop pending alarm on SIGINT
      if ($signal_name eq 'INT') {
        print "Second session stopping...\n";
        $kernel->delay('set an alarm');
      }
    },
  }
);

#==============================================================================
# Tell the kernel to run the sessions.

$poe_kernel->run();

exit;
Something went wrong with that request. Please try again.