Band-aid for segfault in ext/threads/t/blocks.t on SMP machines
[p5sagit/p5-mst-13.2.git] / ext / threads / threads.pm
index fc62b90..04e0692 100755 (executable)
@@ -5,7 +5,7 @@ use 5.008;
 use strict;
 use warnings;
 
-our $VERSION = '1.24_02';
+our $VERSION = '1.36';
 my $XS_VERSION = $VERSION;
 $VERSION = eval $VERSION;
 
@@ -47,7 +47,10 @@ sub import
 
     # Handle args
     while (my $sym = shift) {
-        if ($sym =~ /all/) {
+        if ($sym =~ /^stack/) {
+            threads->set_stack_size(shift);
+
+        } elsif ($sym =~ /all/) {
             push(@EXPORT, qw(yield));
 
         } else {
@@ -61,11 +64,27 @@ sub import
         no strict 'refs';
         *{$caller.'::'.$sym} = \&{$sym};
     }
+
+    # Set stack size via environment variable
+    if (exists($ENV{'PERL5_ITHREADS_STACK_SIZE'})) {
+        threads->set_stack_size($ENV{'PERL5_ITHREADS_STACK_SIZE'});
+    }
 }
 
 
 ### Methods, etc. ###
 
+# Our own exit function/method
+sub exit
+{
+    CORE::exit(0);
+}
+
+# 'Constant' args for threads->list()
+sub threads::all      { }
+sub threads::running  { 1 }
+sub threads::joinable { 0 }
+
 # 'new' is an alias for 'create'
 *new = \&create;
 
@@ -94,15 +113,15 @@ threads - Perl interpreter-based threads
 
 =head1 VERSION
 
-This document describes threads version 1.24
+This document describes threads version 1.36
 
 =head1 SYNOPSIS
 
-    use threads ('yield');
+    use threads ('yield', 'stack_size' => 64*4096);
 
     sub start_thread {
         my @args = @_;
-        print "Thread started: @args\n";
+        print('Thread started: ', join(' ', @args), "\n");
     }
     my $thread = threads->create('start_thread', 'argument');
     $thread->join();
@@ -112,8 +131,11 @@ This document describes threads version 1.24
     my $thread3 = async { foreach (@files) { ... } };
     $thread3->join();
 
-    # Invoke thread in list context so it can return a list
+    # Invoke thread in list context (implicit) so it can return a list
     my ($thr) = threads->create(sub { return (qw/a b c/); });
+    # or specify list context explicitly
+    my $thr = threads->create({'context' => 'list'},
+                              sub { return (qw/a b c/); });
     my @results = $thr->join();
 
     $thread->detach();
@@ -131,10 +153,36 @@ This document describes threads version 1.24
     my @threads = threads->list();
     my $thread_count = threads->list();
 
+    my @running = threads->list(threads::running);
+    my @joinable = threads->list(threads::joinable);
+
     if ($thr1 == $thr2) {
         ...
     }
 
+    $stack_size = threads->get_stack_size();
+    $old_size = threads->set_stack_size(32*4096);
+
+    # Create a thread with a specific context and stack size
+    my $thr = threads->create({ 'context'    => 'list',
+                                'stack_size' => 32*4096 },
+                              \&foo);
+
+    # Get thread's context
+    my $wantarray = $thr->wantarray();
+
+    # Check thread's state
+    if ($thr->is_running()) {
+        sleep(1);
+    }
+    if ($thr->is_joinable()) {
+        $thr->join();
+    }
+
+    $thr->kill('SIGUSR1');
+
+    threads->exit();
+
 =head1 DESCRIPTION
 
 Perl 5.6 introduced something called interpreter threads.  Interpreter threads
@@ -174,22 +222,6 @@ a code ref.
         # or
     my $thr = threads->create(\&func, ...);
 
-The thread may be created in I<list> context, or I<scalar> context as follows:
-
-    # Create thread in list context
-    my ($thr) = threads->create(...);
-
-    # Create thread in scalar context
-    my $thr = threads->create(...);
-
-This has consequences for the C<-E<gt>join()> method describe below.
-
-Although a thread may be created in I<void> context, to do so you must
-I<chain> either the C<-E<gt>join()> or C<-E<gt>detach()> method to the
-C<-E<gt>create()> call:
-
-    threads->create(...)->join();
-
 The C<-E<gt>new()> method is an alias for C<-E<gt>create()>.
 
 =item $thr->join()
@@ -198,31 +230,41 @@ This will wait for the corresponding thread to complete its execution.  When
 the thread finishes, C<-E<gt>join()> will return the return value(s) of the
 entry point function.
 
-The context (void, scalar or list) of the thread creation is also the
-context for C<-E<gt>join()>.  This means that if you intend to return an array
-from a thread, you must use C<my ($thr) = threads->create(...)>, and that
-if you intend to return a scalar, you must use C<my $thr = ...>:
+The context (void, scalar or list) for the return value(s) for C<-E<gt>join()>
+is determined at the time of thread creation.
 
-    # Create thread in list context
+    # Create thread in list context (implicit)
     my ($thr1) = threads->create(sub {
                                     my @results = qw(a b c);
                                     return (@results);
-                                 };
+                                 });
+    #   or (explicit)
+    my $thr1 = threads->create({'context' => 'list'},
+                               sub {
+                                    my @results = qw(a b c);
+                                    return (@results);
+                               });
     # Retrieve list results from thread
     my @res1 = $thr1->join();
 
-    # Create thread in scalar context
+    # Create thread in scalar context (implicit)
     my $thr2 = threads->create(sub {
                                     my $result = 42;
                                     return ($result);
-                                 };
+                                 });
     # Retrieve scalar result from thread
     my $res2 = $thr2->join();
 
-If the program exits without all other threads having been either joined or
-detached, then a warning will be issued. (A program exits either because one
-of its threads explicitly calls L<exit()|perlfunc/"exit EXPR">, or in the case
-of the main thread, reaches the end of the main program file.)
+    # Create a thread in void context (explicit)
+    my $thr3 = threads->create({'void' => 1},
+                               sub { print("Hello, world\n"); });
+    # Join the thread in void context (i.e., no return value)
+    $thr3->join();
+
+See L</"THREAD CONTEXT"> for more details.
+
+If the program exits without all threads having either been joined or
+detached, then a warning will be issued.
 
 Calling C<-E<gt>join()> or C<-E<gt>detach()> on an already joined thread will
 cause an error to be thrown.
@@ -230,7 +272,11 @@ cause an error to be thrown.
 =item $thr->detach()
 
 Makes the thread unjoinable, and causes any eventual return value to be
-discarded.
+discarded.  When the program exits, any detached threads that are still
+running are silently terminated.
+
+If the program exits without all threads having either been joined or
+detached, then a warning will be issued.
 
 Calling C<-E<gt>join()> or C<-E<gt>detach()> on an already detached thread
 will cause an error to be thrown.
@@ -239,6 +285,27 @@ will cause an error to be thrown.
 
 Class method that allows a thread to detach itself.
 
+=item threads->exit()
+
+The usual method for terminating a thread is to
+L<return()|perlfunc/"return EXPR"> from the entry point function with the
+appropriate return value(s).
+
+If needed, a thread can be exited at any time by calling
+C<threads-E<gt>exit()>.  This will cause the thread to return C<undef> in a
+scalar context, or the empty list in a list context.
+
+Calling C<die()> in a thread indicates an abnormal exit for the thread.  Any
+C<$SIG{__DIE__}> handler in the thread will be called first, and then the
+thread will exit with a warning message that will contain any arguments passed
+in the C<die()> call.
+
+Calling C<exit()> in a thread is discouraged, but is equivalent to calling
+C<threads-E<gt>exit()>.
+
+If the desired affect is to truly terminate the application from a thread,
+then use L<POSIX::_exit()|POSIX/"_exit">, if available.
+
 =item threads->self()
 
 Class method that allows a thread to obtain its own I<threads> object.
@@ -270,8 +337,22 @@ code.
 
 =item threads->list()
 
-In a list context, returns a list of all non-joined, non-detached I<threads>
-objects.  In a scalar context, returns a count of the same.
+=item threads->list(threads::all)
+
+=item threads->list(threads::running)
+
+=item threads->list(threads::joinable)
+
+With no arguments (or using C<threads::all>) and in a list context, returns a
+list of all non-joined, non-detached I<threads> objects.  In a scalar context,
+returns a count of the same.
+
+With a I<true> argument (using C<threads::running>), returns a list of all
+non-detached I<threads> objects that are still running.
+
+With a I<false> argument (using C<threads::joinable>), returns a list of all
+non-joined, non-detached I<threads> objects that have finished running (i.e.,
+for which C<-E<gt>join()> will not I<block>).
 
 =item $thr1->equal($thr2)
 
@@ -301,7 +382,7 @@ This I<private> method returns the memory location of the internal thread
 structure associated with a threads object.  For Win32, this is a pointer to
 the C<HANDLE> value returned by C<CreateThread> (i.e., C<HANDLE *>); for other
 platforms, it is a pointer to the C<pthread_t> structure used in the
-C<pthread_create> call (i.e., C<pthread_t *>.
+C<pthread_create> call (i.e., C<pthread_t *>).
 
 This method is of no use for general Perl threads programming.  Its intent is
 to provide other (XS-based) thread modules with the capability to access, and
@@ -314,19 +395,312 @@ Class method that allows a thread to obtain its own I<handle>.
 
 =back
 
+=head1 THREAD STATE
+
+The following boolean methods are useful in determining the I<state> of a
+thread.
+
+=over
+
+=item $thr->is_running()
+
+Returns true if a thread is still running (i.e., if its entry point function
+has not yet finished/exited).
+
+=item $thr->is_joinable()
+
+Returns true if the thread has finished running, is not detached and has not
+yet been joined.  In other works, the thread is ready to be joined and will
+not I<block>.
+
+=item $thr->is_detached()
+
+Returns true if the thread has been detached.
+
+=item threads->is_detached()
+
+Class method that allows a thread to determine whether or not it is detached.
+
+=back
+
+=head1 THREAD CONTEXT
+
+As with subroutines, the type of value returned from a thread's entry point
+function may be determined by the thread's I<context>:  list, scalar or void.
+The thread's context is determined at thread creation.  This is necessary so
+that the context is available to the entry point function via
+L<wantarray()|perlfunc/"wantarray">.  The thread may then specify a value of
+the appropriate type to be returned from C<-E<gt>join()>.
+
+=head2 Explicit context
+
+Because thread creation and thread joining may occur in different contexts, it
+may be desirable to state the context explicitly to the thread's entry point
+function.  This may be done by calling C<-E<gt>create()> with a parameter hash
+as the first argument:
+
+    my $thr = threads->create({'context' => 'list'}, \&foo);
+    ...
+    my @results = $thr->join();
+
+In the above, the threads object is returned to the parent thread in scalar
+context, and the thread's entry point function C<foo> will be called in list
+context such that the parent thread can receive a list from the C<-E<gt>join()>
+call.  Similarly, if you need the threads object, but your thread will not be
+returning a value (i.e., I<void> context), you would do the following:
+
+    my $thr = threads->create({'context' => 'void'}, \&foo);
+    ...
+    $thr->join();
+
+The context type may also be used as the I<key> in the parameter hash followed
+by a I<true> value:
+
+    threads->create({'scalar' => 1}, \&foo);
+    ...
+    my ($thr) = threads->list();
+    my $result = $thr->join();
+
+=head2 Implicit context
+
+If not explicitly stated, the thread's context is implied from the context
+of the C<-E<gt>create()> call:
+
+    # Create thread in list context
+    my ($thr) = threads->create(...);
+
+    # Create thread in scalar context
+    my $thr = threads->create(...);
+
+    # Create thread in void context
+    threads->create(...);
+
+=head2 $thr->wantarray()
+
+This returns the thread's context in the same manner as
+L<wantarray()|perlfunc/"wantarray">.
+
+=head2 threads->wantarray()
+
+Class method to return the current thread's context.  This is the same as
+running L<wantarray()|perlfunc/"wantarray"> in the current thread.
+
+=head1 THREAD STACK SIZE
+
+The default per-thread stack size for different platforms varies
+significantly, and is almost always far more than is needed for most
+applications.  On Win32, Perl's makefile explicitly sets the default stack to
+16 MB; on most other platforms, the system default is used, which again may be
+much larger than is needed.
+
+By tuning the stack size to more accurately reflect your application's needs,
+you may significantly reduce your application's memory usage, and increase the
+number of simultaneously running threads.
+
+N.B., on Windows, Address space allocation granularity is 64 KB, therefore,
+setting the stack smaller than that on Win32 Perl will not save any more
+memory.
+
+=over
+
+=item threads->get_stack_size();
+
+Returns the current default per-thread stack size.  The default is zero, which
+means the system default stack size is currently in use.
+
+=item $size = $thr->get_stack_size();
+
+Returns the stack size for a particular thread.  A return value of zero
+indicates the system default stack size was used for the thread.
+
+=item $old_size = threads->set_stack_size($new_size);
+
+Sets a new default per-thread stack size, and returns the previous setting.
+
+Some platforms have a minimum thread stack size.  Trying to set the stack size
+below this value will result in a warning, and the minimum stack size will be
+used.
+
+Some Linux platforms have a maximum stack size.  Setting too large of a stack
+size will cause thread creation to fail.
+
+If needed, C<$new_size> will be rounded up to the next multiple of the memory
+page size (usually 4096 or 8192).
+
+Threads created after the stack size is set will then either call
+C<pthread_attr_setstacksize()> I<(for pthreads platforms)>, or supply the
+stack size to C<CreateThread()> I<(for Win32 Perl)>.
+
+(Obviously, this call does not affect any currently extant threads.)
+
+=item use threads ('stack_size' => VALUE);
+
+This sets the default per-thread stack size at the start of the application.
+
+=item $ENV{'PERL5_ITHREADS_STACK_SIZE'}
+
+The default per-thread stack size may be set at the start of the application
+through the use of the environment variable C<PERL5_ITHREADS_STACK_SIZE>:
+
+    PERL5_ITHREADS_STACK_SIZE=1048576
+    export PERL5_ITHREADS_STACK_SIZE
+    perl -e'use threads; print(threads->get_stack_size(), "\n")'
+
+This value overrides any C<stack_size> parameter given to C<use threads>.  Its
+primary purpose is to permit setting the per-thread stack size for legacy
+threaded applications.
+
+=item threads->create({'stack_size' => VALUE}, FUNCTION, ARGS)
+
+The stack size an individual threads may also be specified.  This may be done
+by calling C<-E<gt>create()> with a parameter hash as the first argument:
+
+    my $thr = threads->create({'stack_size' => 32*4096}, \&foo, @args);
+
+=item $thr2 = $thr1->create(FUNCTION, ARGS)
+
+This creates a new thread (C<$thr2>) that inherits the stack size from an
+existing thread (C<$thr1>).  This is shorthand for the following:
+
+    my $stack_size = $thr1->get_stack_size();
+    my $thr2 = threads->create({'stack_size' => $stack_size}, FUNCTION, ARGS);
+
+=back
+
+=head1 THREAD SIGNALLING
+
+When safe signals is in effect (the default behavior - see L</"Unsafe signals">
+for more details), then signals may be sent and acted upon by individual
+threads.
+
+=over 4
+
+=item $thr->kill('SIG...');
+
+Sends the specified signal to the thread.  Signal names and (positive) signal
+numbers are the same as those supported by
+L<kill()|perlfunc/"kill SIGNAL, LIST">.  For example, 'SIGTERM', 'TERM' and
+(depending on the OS) 15 are all valid arguments to C<-E<gt>kill()>.
+
+Returns the thread object to allow for method chaining:
+
+    $thr->kill('SIG...')->join();
+
+=back
+
+Signal handlers need to be set up in the threads for the signals they are
+expected to act upon.  Here's an example for I<cancelling> a thread:
+
+    use threads;
+
+    sub thr_func
+    {
+        # Thread 'cancellation' signal handler
+        $SIG{'KILL'} = sub { threads->exit(); };
+
+        ...
+    }
+
+    # Create a thread
+    my $thr = threads->create('thr_func');
+
+    ...
+
+    # Signal the thread to terminate, and then detach
+    # it so that it will get cleaned up automatically
+    $thr->kill('KILL')->detach();
+
+Here's another simplistic example that illustrates the use of thread
+signalling in conjunction with a semaphore to provide rudimentary I<suspend>
+and I<resume> capabilities:
+
+    use threads;
+    use Thread::Semaphore;
+
+    sub thr_func
+    {
+        my $sema = shift;
+
+        # Thread 'suspend/resume' signal handler
+        $SIG{'STOP'} = sub {
+            $sema->down();      # Thread suspended
+            $sema->up();        # Thread resumes
+        };
+
+        ...
+    }
+
+    # Create a semaphore and send it to a thread
+    my $sema = Thread::Semaphore->new();
+    my $thr = threads->create('thr_func', $sema);
+
+    # Suspend the thread
+    $sema->down();
+    $thr->kill('STOP');
+
+    ...
+
+    # Allow the thread to continue
+    $sema->up();
+
+CAVEAT:  The thread signalling capability provided by this module does not
+actually send signals via the OS.  It I<emulates> signals at the Perl-level
+such that signal handlers are called in the appropriate thread.  For example,
+sending C<$thr-E<gt>kill('STOP')> does not actually suspend a thread (or the
+whole process), but does cause a C<$SIG{'STOP'}> handler to be called in that
+thread (as illustrated above).
+
+As such, signals that would normally not be appropriate to use in the
+C<kill()> command (e.g., C<kill('KILL', $$)>) are okay to use with the
+C<-E<gt>kill()> method (again, as illustrated above).
+
+Correspondingly, sending a signal to a thread does not disrupt the operation
+the thread is currently working on:  The signal will be acted upon after the
+current operation has completed.  For instance, if the thread is I<stuck> on
+an I/O call, sending it a signal will not cause the I/O call to be interrupted
+such that the signal is acted up immediately.
+
 =head1 WARNINGS
 
 =over 4
 
-=item A thread exited while # other threads were still running
+=item Perl exited with active threads:
 
-A thread (not necessarily the main thread) exited while there were still other
-threads running.  Usually, it's a good idea to first collect the return values
-of the created threads by joining them, and only then exit from the main
-thread.
+If the program exits without all threads having either been joined or
+detached, then this warning will be issued.
+
+NOTE:  This warning cannot be suppressed using C<no warnings 'threads';> as
+suggested below.
+
+=item Thread creation failed: pthread_create returned #
+
+See the appropriate I<man> page for C<pthread_create> to determine the actual
+cause for the failure.
+
+=item Thread # terminated abnormally: ...
+
+A thread terminated in some manner other than just returning from its entry
+point function.  For example, the thread may have terminated using C<die>.
+
+=item Using minimum thread stack size of #
+
+Some platforms have a minimum thread stack size.  Trying to set the stack size
+below this value will result in the above warning, and the stack size will be
+set to the minimum.
+
+=item Thread creation failed: pthread_attr_setstacksize(I<SIZE>) returned 22
+
+The specified I<SIZE> exceeds the system's maximum stack size.  Use a smaller
+value for the stack size.
 
 =back
 
+If needed, thread warnings can be suppressed by using:
+
+    no warnings 'threads';
+
+in the appropriate scope.
+
 =head1 ERRORS
 
 =over 4
@@ -341,6 +715,23 @@ Perl installation to be rebuilt; it is not just a question of adding the
 L<threads> module (i.e., threaded and non-threaded Perls are binary
 incompatible.)
 
+=item Cannot change stack size of an existing thread
+
+The stack size of currently extant threads cannot be changed, therefore, the
+following results in the above error:
+
+    $thr->set_stack_size($size);
+
+=item Cannot signal threads without safe signals
+
+Safe signals must be in effect to use the C<-E<gt>kill()> signalling method.
+See L</"Unsafe signals"> for more details.
+
+=item Unrecognized signal name: ...
+
+The particular copy of Perl that you're trying to use does not support the
+specified signal being used in a C<-E<gt>kill()> call.
+
 =back
 
 =head1 BUGS
@@ -352,22 +743,42 @@ incompatible.)
 On some platforms, it might not be possible to destroy I<parent> threads while
 there are still existing I<child> threads.
 
-=item Creating threads inside BEGIN blocks
+=item Creating threads inside special blocks
 
-Creating threads inside BEGIN blocks (or during the compilation phase in
-general) does not work.  (In Windows, trying to use fork() inside BEGIN blocks
-is an equally losing proposition, since it has been implemented in very much
-the same way as threads.)
+Creating threads inside C<BEGIN>, C<CHECK> or C<INIT> blocks should not be
+relied upon.  Depending on the Perl version and the application code, results
+may range from success, to (apparently harmless) warnings of leaked scalar, or
+all the way up to crashing of the Perl interpreter.
 
-=item PERL_OLD_SIGNALS are not threadsafe, will not be.
+=item Unsafe signals
 
-If your Perl has been built with PERL_OLD_SIGNALS (one has to explicitly add
-that symbol to I<ccflags>, see C<perl -V>), signal handling is not threadsafe.
+Since Perl 5.8.0, signals have been made safer in Perl by postponing their
+handling until the interpreter is in a I<safe> state.  See
+L<perl58delta/"Safe Signals"> and L<perlipc/"Deferred Signals (Safe Signals)">
+for more details.
+
+Safe signals is the default behavior, and the old, immediate, unsafe
+signalling behavior is only in effect in the following situations:
+
+=over 4
+
+=item * Perl was been built with C<PERL_OLD_SIGNALS> (see C<perl -V>).
+
+=item * The environment variable C<PERL_SIGNALS> is set to C<unsafe> (see L<perlrun/"PERL_SIGNALS">).
+
+=item * The module L<Perl::Unsafe::Signals> is used.
+
+=back
+
+If unsafe signals is in effect, then signal handling is not thread-safe, and
+the C<-E<gt>kill()> signalling method cannot be used.
 
 =item Returning closures from threads
 
-Returning a closure from a thread does not work, usually crashing Perl in the
-process.
+Returning closures from threads should not be relied upon.  Depending of the
+Perl version and the application code, results may range from success, to
+(apparently harmless) warnings of leaked scalar, or all the way up to crashing
+of the Perl interpreter.
 
 =item Perl Bugs and the CPAN Version of L<threads>
 
@@ -393,7 +804,7 @@ L<threads> Discussion Forum on CPAN:
 L<http://www.cpanforum.com/dist/threads>
 
 Annotated POD for L<threads>:
-L<http://annocpan.org/~JDHEDDEN/threads-1.24/shared.pm>
+L<http://annocpan.org/~JDHEDDEN/threads-1.36/threads.pm>
 
 L<threads::shared>, L<perlthrtut>
 
@@ -403,6 +814,9 @@ L<http://www.perl.com/pub/a/2002/09/04/threads.html>
 Perl threads mailing list:
 L<http://lists.cpan.org/showlist.cgi?name=iThreads>
 
+Stack size discussion:
+L<http://www.perlmonks.org/?node_id=532956>
+
 =head1 AUTHOR
 
 Artur Bergman E<lt>sky AT crucially DOT netE<gt>
@@ -424,4 +838,7 @@ Rocco Caputo E<lt>troc AT netrus DOT netE<gt>
 Vipul Ved Prakash E<lt>mail AT vipul DOT netE<gt> -
 Helping with debugging
 
+Dean Arnold E<lt>darnold AT presicient DOT comE<gt> -
+Stack size API
+
 =cut