Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

file 121 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.