1#!/usr/local/bin/perl -w -I.. 2 3# This is a simple test of "package sessions". These are similar to 4# object sessions, but they work with packages instead of objects. It 5# is also a simpler test than sessions.perl. 6 7use strict; 8use lib '../lib'; 9use POE; 10 11#============================================================================== 12# Counter is a package composed of event handler functions. It is 13# never instantiated as an object here. 14 15package Counter; 16use strict; 17use POE::Session; 18 # stupid scope trick, part 1 of 3 19$Counter::name = ''; 20 21#------------------------------------------------------------------------------ 22# This is a normal subroutine, not an object method. It sets up the 23# session's variables and sets the session in motion. 24 25sub _start { 26 my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP]; 27 # register a signal handler 28 $kernel->sig('INT', 'sigint'); 29 # initialize the counter 30 $heap->{'counter'} = 0; 31 # stupid scope trick, part 2 of 3 32 $heap->{'name'} = $Counter::name; 33 # hello, world! 34 print "Session $heap->{'name'} started.\n"; 35 # start things moving 36 $kernel->post($session, 'increment'); 37} 38 39#------------------------------------------------------------------------------ 40# This is a normal subroutine, not an object method. It cleans up 41# after receiving POE's standard _stop event. 42 43sub _stop { 44 my $heap = $_[HEAP]; 45 46 print "Session $heap->{'name'} stopped after $heap->{'counter'} loops.\n"; 47} 48 49#------------------------------------------------------------------------------ 50# This is a normal subroutine, and not an object method. It will be 51# registered as a SIGINT handler so that the session can acknowledge 52# the signal. 53 54sub sigint { 55 my ($heap, $from, $signal_name) = @_[HEAP, SENDER, ARG0]; 56 57 print "$heap->{'name'} caught SIG$signal_name from $from\n"; 58 # did not handle the signal 59 return 0; 60} 61 62#------------------------------------------------------------------------------ 63# This is a normal subroutine, and not an object method. It does most 64# of the counting work. It loops by posting events back to itself. 65# The session exits when there is nothing left to do; this event 66# handler causes that condition when it stops posting events. 67 68sub increment { 69 my ($package, $kernel, $session, $heap) = @_[OBJECT, KERNEL, SESSION, HEAP]; 70 71 $heap->{'counter'}++; 72 73 if ($heap->{counter} % 2) { 74 $kernel->state('runtime_state', $package); 75 } 76 else { 77 $kernel->state('runtime_state'); 78 } 79 80 print "Session $heap->{'name'}, iteration $heap->{'counter'}.\n"; 81 82 if ($heap->{'counter'} < 5) { 83 $kernel->post($session, 'increment'); 84 $kernel->yield('runtime_state', $heap->{counter}); 85 } 86 else { 87 # no more events. since there is nothing left to do, the session exits. 88 } 89} 90 91#------------------------------------------------------------------------------ 92# This state is added on every even count. It's removed on every odd 93# one. Every count posts an event here. 94 95sub runtime_state { 96 my ($session, $heap, $iteration) = @_[SESSION, HEAP, ARG0]; 97 print( 'Session ', $heap->{name}, 98 ' received a runtime_state event during iteration ', 99 $iteration, "\n" 100 ); 101} 102 103#============================================================================== 104# Create ten Counter sessions, all sharing the subs in package 105# Counter. In a way, POE's sessions provide a simple form of object 106# instantiation. 107 108package main; 109 110foreach my $name (qw(one two three four five six seven eight nine ten)) { 111 # stupid scope trick, part 3 of 3 112 $Counter::name = $name; 113 # create the session 114 POE::Session->create( 115 package_states => [ 116 Counter => [ qw(_start _stop increment sigint) ] 117 ] 118 ); 119} 120 121$poe_kernel->run(); 122 123exit; 124 125