use POE;

sub _start {
        my ($kernel, $heap, $name) = @_[KERNEL, HEAP, ARG0];
        $heap->{name} = $name;
    	print "Starting thread $heap->{name}.\n";
        $kernel->delay_add( one => rand(5) );
}

sub one {
        my ($kernel, $heap) = @_[KERNEL, HEAP];
        print "Thread $heap->{name} has reached stage 1.\n";
        $kernel->delay_add( two => rand(5) );
}

sub two {
        my ($kernel, $heap) = @_[KERNEL, HEAP];
        print "Thread $heap->{name} has reached stage 2.\n";
        $kernel->delay_add( three => rand(10) );
}

sub three {
        my ($kernel, $heap) = @_[KERNEL, HEAP];
        print "Thread $heap->{name} has reached stage 3.  Restarting!\n";
        $kernel->delay_add( one => rand(15) );
}

my @threads = qw( A B C D E F G );

foreach (@threads) {
  my ($name) = $_;

  # Sessions act sort of like event-driven threads.  This spawns new
  # ones with the bits of code that they'll run.
  POE::Session->create ( 
  	inline_states => { 
  		_start  => \&_start,
                one     => \&one,
                two     => \&two,
                three	=> \&three,
        },
     	# ARG0 for _start:
      	args => [ $name ],
    );
  
}

$poe_kernel->run();