Bump version of PerlIO::via after last change
[p5sagit/p5-mst-13.2.git] / ext / threads / threads.pm
index 2970321..69214b3 100755 (executable)
@@ -5,7 +5,7 @@ use 5.008;
 use strict;
 use warnings;
 
-our $VERSION = '1.38';
+our $VERSION = '1.57';
 my $XS_VERSION = $VERSION;
 $VERSION = eval $VERSION;
 
@@ -17,9 +17,6 @@ BEGIN {
         die("This Perl not built to support threads\n");
     }
 
-    # Declare that we have been loaded
-    $threads::threads = 1;
-
     # Complain if 'threads' is loaded after 'threads::shared'
     if ($threads::shared::threads_shared) {
         warn <<'_MSG_';
@@ -31,6 +28,9 @@ _MSG_
 }
 
 
+# Declare that we have been loaded
+$threads::threads = 1;
+
 # Load the XS code
 require XSLoader;
 XSLoader::load('threads', $XS_VERSION);
@@ -54,11 +54,15 @@ sub import
             my $flag = shift;
             $threads::thread_exit_only = $flag =~ /^thread/i;
 
-        } elsif ($sym =~ /all/) {
+        } elsif ($sym =~ /^str/i) {
+            import overload ('""' => \&tid);
+
+        } elsif ($sym =~ /(?:all|yield)/) {
             push(@EXPORT, qw(yield));
 
         } else {
-            push(@EXPORT, $sym);
+            require Carp;
+            Carp::croak("threads: Unknown import option: $sym");
         }
     }
 
@@ -129,23 +133,29 @@ threads - Perl interpreter-based threads
 
 =head1 VERSION
 
-This document describes threads version 1.38
+This document describes threads version 1.57
 
 =head1 SYNOPSIS
 
-    use threads ('yield', 'stack_size' => 64*4096, 'exit' => 'threads_only');
+    use threads ('yield',
+                 'stack_size' => 64*4096,
+                 'exit' => 'threads_only',
+                 'stringify');
 
     sub start_thread {
         my @args = @_;
         print('Thread started: ', join(' ', @args), "\n");
     }
-    my $thread = threads->create('start_thread', 'argument');
-    $thread->join();
+    my $thr = threads->create('start_thread', 'argument');
+    $thr->join();
 
     threads->create(sub { print("I am a thread\n"); })->join();
 
-    my $thread3 = async { foreach (@files) { ... } };
-    $thread3->join();
+    my $thr2 = async { foreach (@files) { ... } };
+    $thr2->join();
+    if (my $err = $thr2->error()) {
+        warn("Thread error: $err\n");
+    }
 
     # Invoke thread in list context (implicit) so it can return a list
     my ($thr) = threads->create(sub { return (qw/a b c/); });
@@ -154,16 +164,16 @@ This document describes threads version 1.38
                               sub { return (qw/a b c/); });
     my @results = $thr->join();
 
-    $thread->detach();
+    $thr->detach();
 
     # Get a thread's object
-    $thread = threads->self();
-    $thread = threads->object($tid);
+    $thr = threads->self();
+    $thr = threads->object($tid);
 
     # Get a thread's ID
     $tid = threads->tid();
-    $tid = threads->self->tid();
-    $tid = $thread->tid();
+    $tid = $thr->tid();
+    $tid = "$thr";
 
     # Give other threads a chance to run
     threads->yield();
@@ -323,6 +333,17 @@ thread in a program being 0, and incrementing by 1 for every thread created.
 
 Class method that allows a thread to obtain its own ID.
 
+=item "$thr"
+
+If you add the C<stringify> import option to your C<use threads> declaration,
+then using a threads object in a string or a string context (e.g., as a hash
+key) will cause its ID to be used as the value:
+
+    use threads qw(stringify);
+
+    my $thr = threads->create(...);
+    print("Thread $thr started...\n");  # Prints out: Thread 1 started...
+
 =item threads->object($tid)
 
 This will return the I<threads> object for the I<active> thread associated
@@ -352,7 +373,7 @@ 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.
+non-joined, 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.,
@@ -380,6 +401,12 @@ it.  This block is treated as an anonymous subroutine, and so must have a
 semi-colon after the closing brace.  Like C<threads->create()>, C<async>
 returns a I<threads> object.
 
+=item $thr->error()
+
+Threads are executed in an C<eval> context.  This method will return C<undef>
+if the thread terminates I<normally>.  Otherwise, it returns the value of
+C<$@> associated with the thread's execution status in its C<eval> context.
+
 =item $thr->_handle()
 
 This I<private> method returns the memory location of the internal thread
@@ -763,7 +790,8 @@ 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>.
+point function, or by using C<threads-E<gt>exit()>.  For example, the thread
+may have terminated because of a error, or by using C<die>.
 
 =item Using minimum thread stack size of #
 
@@ -817,10 +845,41 @@ specified signal being used in a C<-E<gt>kill()> call.
 
 =back
 
-=head1 BUGS
+=head1 BUGS AND LIMITATIONS
+
+Before you consider posting a bug report, please consult, and possibly post a
+message to the discussion forum to see if what you've encountered is a known
+problem.
 
 =over
 
+=item Using non-threadsafe modules
+
+Unfortunately, you may encounter Perl modules are not I<threadsafe>.  For
+example, they may crash the Perl interpreter during execution, or may dump
+core on termination.  Depending on the module and the requirements of your
+application, it may be possible to work around such difficulties.
+
+If the module will only be used inside a thread, you can try loading the
+module from inside the thread entry point function using C<require> (and
+C<import> if needed):
+
+    sub thr_func
+    {
+        require Unsafe::Module
+        # import Unsafe::Module ...;
+
+        ....
+    }
+
+If the module is needed inside the I<main> thread, try modifying your
+application so that the module is loaded (again using C<require> and
+C<import>) after any threads are started, and in such a way that no other
+threads are started afterwards.
+
+If the above does not work, or is not adequate for your application, then file
+a bug report on L<http://rt.cpan.org/Public/> against the problematic module.
+
 =item Parent-child threads
 
 On some platforms, it might not be possible to destroy I<parent> threads while
@@ -863,6 +922,13 @@ 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 Returning objects from threads
+
+Returning objects from threads does not work.  Depending on the classes
+involved, you may be able to work around this by returning a serialized
+version of the object (e.g., using L<Data::Dumper> or L<Storable>), and then
+reconstituting it in the joining thread.
+
 =item Perl Bugs and the CPAN Version of L<threads>
 
 Support for threads extents beyond the code in this module (i.e.,
@@ -871,10 +937,6 @@ versions of Perl contain bugs that may manifest themselves despite using the
 latest version of L<threads> from CPAN.  There is no workaround for this other
 than upgrading to the lastest version of Perl.
 
-(Before you consider posting a bug report, please consult, and possibly post a
-message to the discussion forum to see if what you've encountered is a known
-problem.)
-
 =back
 
 =head1 REQUIREMENTS
@@ -887,7 +949,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.38/threads.pm>
+L<http://annocpan.org/~JDHEDDEN/threads-1.57/threads.pm>
 
 L<threads::shared>, L<perlthrtut>