NAME

Thread::App::Shutdown - a singleton to manage shutdown of a threaded application

SYNOPSIS

use Thread::App::Shutdown;
my $shutdown = Thread::App::Shutdown->instance;
my $transactions = 0;
while( 1 ) {
   last if $shutdown->get();
   # do something monumentous
   if( ++$transactions > 1000 ) {
       $shutdown->set();
   }
}

DESCRIPTION

                 *** A note of CAUTION ***

This module only functions on Perl version 5.8.0 and later.
And then only when threads are enabled with -Dusethreads.  It
is of no use with any version of Perl before 5.8.0 or without
threads enabled.

                 *************************

Thread::App::Shutdown provides a singleton that can be used by multiple threads to coordinate the clean shutdown of a threaded application.

In a large threaded application, you might have one or more pools of worker threads plus a coordination thread, a thread receiving signals and a dedicated thread feeding input from some external source into the worker pool(s). When some predefined event happens (SIGTERM received, a particular type of input is received, x number of transactions have been processed by the worker pool, etc.), the application should shut down.

To effect this, you can create a shared variable for each of the event types and pass references to the variable to all of the discrete program units, or you can break with OO and have a single shared global variable that all program units look at as $main::shutdown or $Foo::shutdown.

Thread::App::Shutdown makes the second option cleaner. Anywhere in the program that the shutdown state has to be set or queried, simply retrieve an instance of Thread::App::Shutdown and call it's methods.

INSTANCE ACCESSOR

Because Thread::App::Shutdown is a singleton, you don't construct it with ->new(). To get a copy of the one and only object, use the ->instance() accessor.

If an instance of the class does not already exist, one will be created and returned. All subsequent uses of ->instance will return the same object. As such, it is important that the first instance of the Thread::App::Shutdown object be created prior to any other threads. Typically you would get the instance as part of the program initialization.

METHODS

set()

The set() method sets the flag to indicate that shutdown is pending. It returns the previous value of the shutdown flag.

get()

The get() method returns a true value or undef to indicate whether the shutdown flag is set or not.

my $shutdown = Thread::App::Shutdown->instance; lives_ok { $shutdown->set( 1 ) } 'set flag to 1'; is( $shutdown->get, 1, 'flag is set');

clear()

The clear() method resets the shutdown flag to indicate that shutdown is not pending. It also returns the previous value of the shutdown flag.

EXAMPLES

In your main program:

use threads;
use Thread::App::Shutdown;
my $shutdown = Thread::App::Shutdown->instance;
my $foo = Foo->new;
my $thread = $foo->run;
$SIG{TERM} = sub { $shutdown->set };
$thread->join;

In Foo.pm:

package Foo;
use threads;
use Thread::App::Shutdown;
sub new { bless {}, $_[0] }
sub run {
    my $shutdown = Thread::App::Shutdown->new;
    return threads->create( sub {
        while( 1 ) {
            last if( $shutdown->get );
            print "no shutdown yet\n";
            sleep(10);
        }
    } );
}
1;

This example is likely to work only on thread implementations that use pseudo-processes. On other thread implementations, POSIX::SigAction has to be used to ensure that only the main thread receives SIGTERM.

SEE ALSO

threads & threads::shared

Thread::SigHandler

Thread::Signal by Elizabeth Mattijsen.

AUTHOR

James FitzGibbon, <jfitz@CPAN.org>

COPYRIGHT

Copyright (c) 2003 James FitzGibbon. All Rights Reserved.

This module is free software; you may use it under the same terms as Perl itself.