The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Thread::Exit - provide thread-local exit(), BEGIN {}, END {} and exited()

SYNOPSIS

    use Thread::Exit ();   # just make exit() thread local

    use Thread::Exit
     begin => 'begin_sub', # sub to exec at beginning of thread (default: none)
     end => 'end_sub',     # sub to exec at end of thread (default: none)
     inherit => 1,         # make all new threads inherit (default: 1)
    ;

    $thread = threads->new( sub { exit( "We've exited" ) } ); # or "create"
    print $thread->join;            # prints "We've exited"

    Thread::Exit->ismain;           # mark this thread as main thread

    Thread::Exit->begin( \$begin_sub ); # set/adapt BEGIN sub later
    Thread::Exit->begin( undef );       # disable BEGIN sub
    $begin = Thread::Exit->begin;

    Thread::Exit->end( \$end_sub ); # set/adapt END sub later
    Thread::Exit->end( undef );     # disable END sub
    $end = Thread::Exit->end;

    Thread::Exit->inherit( 1 );     # make all new threads inherit settings
    Thread::Exit->inherit( 0 );     # new threads won't inherit settings
    $inherit = Thread::Exit->inherit;

DESCRIPTION

                  *** A note of CAUTION ***

 This module only functions on Perl versions 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.

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

This module adds three features to threads that are sorely missed by some.

The first feature is that you can use exit() within a thread to return() from that thread only. Without this module, exit() stops all threads and exits to the calling process (which usually is the operating system). With this module, exit() functions just as return() (including passing back values to the parent thread).

The second feature is that you can specify a subroutine that will be executed after the thread is started, but before the subroutine of which the thread consists, is started. This is an alternate implementation of the CLONE subroutine, which differs by being really executed inside the context of the new thread (as shown by the value of threads-tid>). Multiple "begin" subroutines can be chained together if necessary.

The third feature is that you can specify a subroutine that will be executed after the thread is done, but before the thread returns to the parent thread. This is similar to the END subroutine, but on a per-thread basis. Multiple "end" subroutines can be chained together if necessary.

CLASS METHODS

These are the class methods.

begin

 Thread::Exit->begin( 'begin' );             # execute "begin"

 Thread::Exit->begin( undef );               # don't execute anything

 Thread::Exit->begin( 'module::before',-1 ); # execute "module::before" first

 Thread::Exit->begin( \&after,1 );           # execute "after" last

 $begin = Thread::Exit->begin;               # return current code reference

The "begin" class method sets and returns the subroutine that will be executed after the current thread is started but before it starts the actual subroutine of which the thread consists. It is similar to the CLONE subroutine, but is really executed in the context of the thread (whereas CLONE currently fakes this for performance reasons, causing XS routines and threads->tid to be executed in the wrong context).

The first input parameter is the name or a reference to the subroutine that should be executed before this thread really starts. It can be specified as a name or as a code reference. No changes will be made if no parameters are specified. If the first parameter is undef()ined or empty, then no subroutine will be executed when this thread has started.

The second input parameter only has meaning if there has been a "begin" subroutine specified before. The following values are recognized:

replace (0)

If the value 0 is specified, then the new subroutine specification will replace any current "begin" subroutine specification done earlier. This is the default.

after (1)

If the value 1 is specified, then the subroutine specificed will be executed after any other "begin" subroutine that was specified earlier.

before (-1)

If the value -1 is specified, then the subroutine specificed will be executed before any other "begin" subroutine that was specified earlier.

By default, new threads inherit the settings of the "begin" subroutine. Check the inherit method to change this.

end

 Thread::Exit->end( 'end' );               # execute "end"

 Thread::Exit->end( undef );               # don't execute anything

 Thread::Exit->end( 'module::before',-1 ); # execute "module::before" first

 Thread::Exit->end( \&after,1 );           # execute "after" last

 $end = Thread::Exit->end;                 # return current code reference

The "end" class method sets and returns the subroutine that will be executed after the current thread is finished but before it will return via a join().

The "end" subroutine is passed a single flag which is true if the thread is exiting by calling exit(). Please note that the system variable $@ is also set if the thread exited because of a compilation or execution error.

The first input parameter is the name or a reference to the subroutine that should be executed after this thread is finished. It can be specified as a name or as a code reference. No changes will be made if no parameters are specified. If the first parameter is undef()ined or empty, then no subroutine will be executed when this thread ends.

The second input parameter only has meaning if there has been an "end" subroutine specified before. The following values are recognized:

replace (0)

If the value 0 is specified, then the new subroutine specification will replace any current "end" subroutine specification done earlier. This is the default.

after (1)

If the value 1 is specified, then the subroutine specificed will be executed after any other "end" subroutine that was specified earlier.

before (-1)

If the value -1 is specified, then the subroutine specificed will be executed before any other "end" subroutine that was specified earlier.

By default, new threads inherit the settings of the "end" subroutine. Check the inherit method to change this.

inherit

 Thread::Exit->inherit( 1 );         # default, new threads inherit

 Thread::Exit->inherit( 0 );         # new threads don't inherit

 $inherit = Thread::Exit->inherit;   # return current setting

The "inherit" class method sets and returns whether newly created threads will inherit the "begin" and "end" subroutine settings (as previously indicated with a call to the begin or end class methods).

If an input parameter is specified, it indicates the new setting of this flag. A true value indicates that new threads should inherit the "begin" and "end" subroutine settings. A false value indicates that new threads should not have any "begin" or "end" subroutine (unless of course specified otherwise inside the thread after the thread has started).

The default settings is 1, causing begin and end settings to be inherited by newly created threads.

ismain

 Thread::Exit->ismain;

The "ismain" class method is only needed in very special situation. It marks the current thread as the "main" thread from which a "real" exit() should occur.

By default, only the thread in which the use Thread::Exit occurred, will perform a "real" exit (either to CORE::exit() or to Apache::exit() when in a mod_perl environment). This may however, not always be right. In those cases you can use this class method.

REQUIRED MODULES

 load (0.12)

MOD_PERL

To allow this module to function under Apache with mod_perl, a special check is included for the existence of the Apache::exit() subroutine. If the Apache::exit() subroutine exists, then that exit routine will be preferred over the CORE::exit() routine when exiting from the thread in which the first use Thread::Exit occurred.

TODO

Examples should be added.

AUTHOR

Elizabeth Mattijsen, <liz@dijkmat.nl>.

Please report bugs to <perlbugs@dijkmat.nl>.

ACKNOWLEDGEMENTS

Nick Ing-Simmons and Rafael Garcia-Suarez for their suggestions and support. Mike Pomraning for pointing out that die() can also take a reference as a parameter inside an eval(), so that the dependency on Thread::Serialize could be removed.

COPYRIGHT

Copyright (c) 2002-2003 Elizabeth Mattijsen <liz@dijkmat.nl>. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

threads.