POE handles signals immediately by simply enqueuing them. These do not get handled until they are dispatched i.e. until your program releases control back to the kernel. This means that whilst your code is running (like inside of a handler) you can press Ctrl-C till you're blue in the face and the program won't end. The minute your handler finishes, POE dispatches and handles the request and the program dies.

for some diagnostics it can be useful to turn assertions on. This can be done by inserting the code as shown below. Notice the subs have to be defined before use()ing POE!

sub POE::Kernel::ASSERT_DEFAULT () { 1 }
sub POE::Kernel::TRACE_SIGNALS ()  { 1 }

use POE;

if you have long running handlers that will hog the process, see: http://poe.perl.org/?POE_Cookbook/Looping for an idea of how to restructure it.