Sometimes programs won't stop when they should.

It's important to know that POE programs only stop after all their sessions do. The important question then becomes: Why aren't my sessions stopping?

To understand that, you first need to know what keeps them running.

Sessions are kept alive by virtue of the resources they watch. POE assumes that sessions with one or more significant resources still has something to do. Contrawise, a session with none of these resources has gone inert and is free to be destroyed.

These are the significant resources that keep sessions alive, and the functions that allocate them.

  $kernel->alarm()
  $kernel->alarm_add()
  $kernel->alarm_adjust()
  $kernel->alarm_set()
  $kernel->delay()
  $kernel->delay_add()
  $kernel->delay_set()

  $kernel->post()
  $kernel->yield()

  $kernel->select()
  $kernel->select_read()
  $kernel->select_write()
  $kernel->select_expedite()
  POE::Wheel::Xyz->new()

  $kernel->sig_child()

  $kernel->refcount_increment()

  $kernel->alias_set()

To allow a session to hang around without having any other resources, an alias can be set. Alternatively the reference count of the session can get incremented. The advantage of an alias is that it will allow a session to die if there are no more active sessions i.e. unlike as with the the reference count which MUST be decremented before the session can expire, an alias doesn't need clearing.

(A "child" session is one that was created from an existing session's event handler. POE keeps track of these relationships, and parents will remain active as long as they have at least one child session.)

  POE::Session->create()
  POE::NFA->spawn()

Sometimes it's hard to tell what resources are still out there keeping sessions alive. POE::Kernel keeps track of them, and there is a way to trace its "garbage collection". Define the constant POE::Kernel::TRACE_REFCNT before using the first POE module, and you will receive a dump of which resources are in use throughout your program's lifetime.

#!/usr/bin/perl -w

use strict;

sub POE::Kernel::TRACE_REFCNT () { 1 }
use POE;

# ...

$poe_kernel->run();
exit 0;

Stuck programs do so either by looping or hanging. If your program loops, you'll see the same resource counts over and over. They are likely to be the droids you're looking for. If it hangs, however, the final resource dumps are probably significant.