9 my $XS_VERSION = $VERSION;
10 $VERSION = eval $VERSION;
14 # Verify this Perl supports threads
16 if (! $Config{useithreads}) {
17 die("This Perl not built to support threads\n");
20 # Complain if 'threads' is loaded after 'threads::shared'
21 if ($threads::shared::threads_shared) {
23 Warning, threads::shared has already been loaded. To
24 enable shared variables, 'use threads' must be called
25 before threads::shared or any module that uses it.
31 # Declare that we have been loaded
32 $threads::threads = 1;
36 XSLoader::load('threads', $XS_VERSION);
43 my $class = shift; # Not used
45 # Exported subroutines
46 my @EXPORT = qw(async);
49 while (my $sym = shift) {
50 if ($sym =~ /^stack/i) {
51 threads->set_stack_size(shift);
53 } elsif ($sym =~ /^exit/i) {
55 $threads::thread_exit_only = $flag =~ /^thread/i;
57 } elsif ($sym =~ /^str/i) {
58 import overload ('""' => \&tid);
60 } elsif ($sym =~ /all/) {
61 push(@EXPORT, qw(yield));
68 # Export subroutine names
69 my $caller = caller();
70 foreach my $sym (@EXPORT) {
72 *{$caller.'::'.$sym} = \&{$sym};
75 # Set stack size via environment variable
76 if (exists($ENV{'PERL5_ITHREADS_STACK_SIZE'})) {
77 threads->set_stack_size($ENV{'PERL5_ITHREADS_STACK_SIZE'});
84 # Exit from a thread (only)
87 my ($class, $status) = @_;
88 if (! defined($status)) {
95 Carp::croak("Usage: threads->exit(status)");
98 $class->set_thread_exit_only(1);
102 # 'Constant' args for threads->list()
104 sub threads::running { 1 }
105 sub threads::joinable { 0 }
107 # 'new' is an alias for 'create'
110 # 'async' is a function alias for the 'threads->create()' method
113 unshift(@_, 'threads');
114 # Use "goto" trick to avoid pad problems from 5.8.1 (fixed in 5.8.2)
118 # Thread object equality checking
121 '!=' => sub { ! equal(@_) },
131 threads - Perl interpreter-based threads
135 This document describes threads version 1.43
139 use threads ('yield',
140 'stack_size' => 64*4096,
141 'exit' => 'threads_only',
146 print('Thread started: ', join(' ', @args), "\n");
148 my $thr = threads->create('start_thread', 'argument');
151 threads->create(sub { print("I am a thread\n"); })->join();
153 my $thr2 = async { foreach (@files) { ... } };
156 # Invoke thread in list context (implicit) so it can return a list
157 my ($thr) = threads->create(sub { return (qw/a b c/); });
158 # or specify list context explicitly
159 my $thr = threads->create({'context' => 'list'},
160 sub { return (qw/a b c/); });
161 my @results = $thr->join();
165 # Get a thread's object
166 $thr = threads->self();
167 $thr = threads->object($tid);
170 $tid = threads->tid();
174 # Give other threads a chance to run
178 # Lists of non-detached threads
179 my @threads = threads->list();
180 my $thread_count = threads->list();
182 my @running = threads->list(threads::running);
183 my @joinable = threads->list(threads::joinable);
185 # Test thread objects
186 if ($thr1 == $thr2) {
190 # Manage thread stack size
191 $stack_size = threads->get_stack_size();
192 $old_size = threads->set_stack_size(32*4096);
194 # Create a thread with a specific context and stack size
195 my $thr = threads->create({ 'context' => 'list',
196 'stack_size' => 32*4096,
197 'exit' => 'thread_only' },
200 # Get thread's context
201 my $wantarray = $thr->wantarray();
203 # Check thread's state
204 if ($thr->is_running()) {
207 if ($thr->is_joinable()) {
211 # Send a signal to a thread
212 $thr->kill('SIGUSR1');
219 Perl 5.6 introduced something called interpreter threads. Interpreter threads
220 are different from I<5005threads> (the thread model of Perl 5.005) by creating
221 a new Perl interpreter per thread, and not sharing any data or state between
224 Prior to Perl 5.8, this has only been available to people embedding Perl, and
225 for emulating fork() on Windows.
227 The I<threads> API is loosely based on the old Thread.pm API. It is very
228 important to note that variables are not shared between threads, all variables
229 are by default thread local. To use shared variables one must use
232 It is also important to note that you must enable threads by doing C<use
233 threads> as early as possible in the script itself, and that it is not
234 possible to enable threading inside an C<eval "">, C<do>, C<require>, or
235 C<use>. In particular, if you are intending to share variables with
236 L<threads::shared>, you must C<use threads> before you C<use threads::shared>.
237 (C<threads> will emit a warning if you do it the other way around.)
241 =item $thr = threads->create(FUNCTION, ARGS)
243 This will create a new thread that will begin execution with the specified
244 entry point function, and give it the I<ARGS> list as parameters. It will
245 return the corresponding threads object, or C<undef> if thread creation failed.
247 I<FUNCTION> may either be the name of a function, an anonymous subroutine, or
250 my $thr = threads->create('func_name', ...);
252 my $thr = threads->create(sub { ... }, ...);
254 my $thr = threads->create(\&func, ...);
256 The C<-E<gt>new()> method is an alias for C<-E<gt>create()>.
260 This will wait for the corresponding thread to complete its execution. When
261 the thread finishes, C<-E<gt>join()> will return the return value(s) of the
262 entry point function.
264 The context (void, scalar or list) for the return value(s) for C<-E<gt>join()>
265 is determined at the time of thread creation.
267 # Create thread in list context (implicit)
268 my ($thr1) = threads->create(sub {
269 my @results = qw(a b c);
273 my $thr1 = threads->create({'context' => 'list'},
275 my @results = qw(a b c);
278 # Retrieve list results from thread
279 my @res1 = $thr1->join();
281 # Create thread in scalar context (implicit)
282 my $thr2 = threads->create(sub {
286 # Retrieve scalar result from thread
287 my $res2 = $thr2->join();
289 # Create a thread in void context (explicit)
290 my $thr3 = threads->create({'void' => 1},
291 sub { print("Hello, world\n"); });
292 # Join the thread in void context (i.e., no return value)
295 See L</"THREAD CONTEXT"> for more details.
297 If the program exits without all threads having either been joined or
298 detached, then a warning will be issued.
300 Calling C<-E<gt>join()> or C<-E<gt>detach()> on an already joined thread will
301 cause an error to be thrown.
305 Makes the thread unjoinable, and causes any eventual return value to be
306 discarded. When the program exits, any detached threads that are still
307 running are silently terminated.
309 If the program exits without all threads having either been joined or
310 detached, then a warning will be issued.
312 Calling C<-E<gt>join()> or C<-E<gt>detach()> on an already detached thread
313 will cause an error to be thrown.
315 =item threads->detach()
317 Class method that allows a thread to detach itself.
319 =item threads->self()
321 Class method that allows a thread to obtain its own I<threads> object.
325 Returns the ID of the thread. Thread IDs are unique integers with the main
326 thread in a program being 0, and incrementing by 1 for every thread created.
330 Class method that allows a thread to obtain its own ID.
334 If you add the C<stringify> import option to your C<use threads> declaration,
335 then using a threads object in a string or a string context (e.g., as a hash
336 key) will cause its ID to be used as the value:
338 use threads qw(stringify);
340 my $thr = threads->create(...);
341 print("Thread $thr started...\n"); # Prints out: Thread 1 started...
343 =item threads->object($tid)
345 This will return the I<threads> object for the I<active> thread associated
346 with the specified thread ID. Returns C<undef> if there is no thread
347 associated with the TID, if the thread is joined or detached, if no TID is
348 specified or if the specified TID is undef.
350 =item threads->yield()
352 This is a suggestion to the OS to let this thread yield CPU time to other
353 threads. What actually happens is highly dependent upon the underlying
354 thread implementation.
356 You may do C<use threads qw(yield)>, and then just use C<yield()> in your
359 =item threads->list()
361 =item threads->list(threads::all)
363 =item threads->list(threads::running)
365 =item threads->list(threads::joinable)
367 With no arguments (or using C<threads::all>) and in a list context, returns a
368 list of all non-joined, non-detached I<threads> objects. In a scalar context,
369 returns a count of the same.
371 With a I<true> argument (using C<threads::running>), returns a list of all
372 non-detached I<threads> objects that are still running.
374 With a I<false> argument (using C<threads::joinable>), returns a list of all
375 non-joined, non-detached I<threads> objects that have finished running (i.e.,
376 for which C<-E<gt>join()> will not I<block>).
378 =item $thr1->equal($thr2)
380 Tests if two threads objects are the same thread or not. This is overloaded
381 to the more natural forms:
383 if ($thr1 == $thr2) {
384 print("Threads are the same\n");
387 if ($thr1 != $thr2) {
388 print("Threads differ\n");
391 (Thread comparison is based on thread IDs.)
395 C<async> creates a thread to execute the block immediately following
396 it. This block is treated as an anonymous subroutine, and so must have a
397 semi-colon after the closing brace. Like C<threads->create()>, C<async>
398 returns a I<threads> object.
400 =item $thr->_handle()
402 This I<private> method returns the memory location of the internal thread
403 structure associated with a threads object. For Win32, this is a pointer to
404 the C<HANDLE> value returned by C<CreateThread> (i.e., C<HANDLE *>); for other
405 platforms, it is a pointer to the C<pthread_t> structure used in the
406 C<pthread_create> call (i.e., C<pthread_t *>).
408 This method is of no use for general Perl threads programming. Its intent is
409 to provide other (XS-based) thread modules with the capability to access, and
410 possibly manipulate, the underlying thread structure associated with a Perl
413 =item threads->_handle()
415 Class method that allows a thread to obtain its own I<handle>.
419 =head1 EXITING A THREAD
421 The usual method for terminating a thread is to
422 L<return()|perlfunc/"return EXPR"> from the entry point function with the
423 appropriate return value(s).
427 =item threads->exit()
429 If needed, a thread can be exited at any time by calling
430 C<threads-E<gt>exit()>. This will cause the thread to return C<undef> in a
431 scalar context, or the empty list in a list context.
433 When called from the I<main> thread, this behaves the same as C<exit(0)>.
435 =item threads->exit(status)
437 When called from a thread, this behaves like C<threads-E<gt>exit()> (i.e., the
438 exit status code is ignored).
440 When called from the I<main> thread, this behaves the same as C<exit(status)>.
444 Calling C<die()> in a thread indicates an abnormal exit for the thread. Any
445 C<$SIG{__DIE__}> handler in the thread will be called first, and then the
446 thread will exit with a warning message that will contain any arguments passed
447 in the C<die()> call.
451 Calling L<exit()|perlfunc/"exit EXPR"> inside a thread causes the whole
452 application to terminate. Because of this, the use of C<exit()> inside
453 threaded code, or in modules that might be used in threaded applications, is
454 strongly discouraged.
456 If C<exit()> really is needed, then consider using the following:
458 threads->exit() if threads->can('exit'); # Thread friendly
461 =item use threads 'exit' => 'thread_only'
463 This globally overrides the default behavior of calling C<exit()> inside a
464 thread, and effectively causes such calls to behave the same as
465 C<threads-E<gt>exit()>. In other words, with this setting, calling C<exit()>
466 causes only the thread to terminate.
468 Because of its global effect, this setting should not be used inside modules
471 The I<main> thread is unaffected by this setting.
473 =item threads->create({'exit' => 'thread_only'}, ...)
475 This overrides the default behavior of C<exit()> inside the newly created
478 =item $thr->set_thread_exit_only(boolean)
480 This can be used to change the I<exit thread only> behavior for a thread after
481 it has been created. With a I<true> argument, C<exit()> will cause the only
482 the thread to exit. With a I<false> argument, C<exit()> will terminate the
485 The I<main> thread is unaffected by this call.
487 =item threads->set_thread_exit_only(boolean)
489 Class method for use inside a thread to changes its own behavior for
492 The I<main> thread is unaffected by this call.
498 The following boolean methods are useful in determining the I<state> of a
503 =item $thr->is_running()
505 Returns true if a thread is still running (i.e., if its entry point function
506 has not yet finished/exited).
508 =item $thr->is_joinable()
510 Returns true if the thread has finished running, is not detached and has not
511 yet been joined. In other works, the thread is ready to be joined and will
514 =item $thr->is_detached()
516 Returns true if the thread has been detached.
518 =item threads->is_detached()
520 Class method that allows a thread to determine whether or not it is detached.
524 =head1 THREAD CONTEXT
526 As with subroutines, the type of value returned from a thread's entry point
527 function may be determined by the thread's I<context>: list, scalar or void.
528 The thread's context is determined at thread creation. This is necessary so
529 that the context is available to the entry point function via
530 L<wantarray()|perlfunc/"wantarray">. The thread may then specify a value of
531 the appropriate type to be returned from C<-E<gt>join()>.
533 =head2 Explicit context
535 Because thread creation and thread joining may occur in different contexts, it
536 may be desirable to state the context explicitly to the thread's entry point
537 function. This may be done by calling C<-E<gt>create()> with a parameter hash
538 as the first argument:
540 my $thr = threads->create({'context' => 'list'}, \&foo);
542 my @results = $thr->join();
544 In the above, the threads object is returned to the parent thread in scalar
545 context, and the thread's entry point function C<foo> will be called in list
546 context such that the parent thread can receive a list from the C<-E<gt>join()>
547 call. Similarly, if you need the threads object, but your thread will not be
548 returning a value (i.e., I<void> context), you would do the following:
550 my $thr = threads->create({'context' => 'void'}, \&foo);
554 The context type may also be used as the I<key> in the parameter hash followed
557 threads->create({'scalar' => 1}, \&foo);
559 my ($thr) = threads->list();
560 my $result = $thr->join();
562 =head2 Implicit context
564 If not explicitly stated, the thread's context is implied from the context
565 of the C<-E<gt>create()> call:
567 # Create thread in list context
568 my ($thr) = threads->create(...);
570 # Create thread in scalar context
571 my $thr = threads->create(...);
573 # Create thread in void context
574 threads->create(...);
576 =head2 $thr->wantarray()
578 This returns the thread's context in the same manner as
579 L<wantarray()|perlfunc/"wantarray">.
581 =head2 threads->wantarray()
583 Class method to return the current thread's context. This is the same as
584 running L<wantarray()|perlfunc/"wantarray"> in the current thread.
586 =head1 THREAD STACK SIZE
588 The default per-thread stack size for different platforms varies
589 significantly, and is almost always far more than is needed for most
590 applications. On Win32, Perl's makefile explicitly sets the default stack to
591 16 MB; on most other platforms, the system default is used, which again may be
592 much larger than is needed.
594 By tuning the stack size to more accurately reflect your application's needs,
595 you may significantly reduce your application's memory usage, and increase the
596 number of simultaneously running threads.
598 N.B., on Windows, Address space allocation granularity is 64 KB, therefore,
599 setting the stack smaller than that on Win32 Perl will not save any more
604 =item threads->get_stack_size();
606 Returns the current default per-thread stack size. The default is zero, which
607 means the system default stack size is currently in use.
609 =item $size = $thr->get_stack_size();
611 Returns the stack size for a particular thread. A return value of zero
612 indicates the system default stack size was used for the thread.
614 =item $old_size = threads->set_stack_size($new_size);
616 Sets a new default per-thread stack size, and returns the previous setting.
618 Some platforms have a minimum thread stack size. Trying to set the stack size
619 below this value will result in a warning, and the minimum stack size will be
622 Some Linux platforms have a maximum stack size. Setting too large of a stack
623 size will cause thread creation to fail.
625 If needed, C<$new_size> will be rounded up to the next multiple of the memory
626 page size (usually 4096 or 8192).
628 Threads created after the stack size is set will then either call
629 C<pthread_attr_setstacksize()> I<(for pthreads platforms)>, or supply the
630 stack size to C<CreateThread()> I<(for Win32 Perl)>.
632 (Obviously, this call does not affect any currently extant threads.)
634 =item use threads ('stack_size' => VALUE);
636 This sets the default per-thread stack size at the start of the application.
638 =item $ENV{'PERL5_ITHREADS_STACK_SIZE'}
640 The default per-thread stack size may be set at the start of the application
641 through the use of the environment variable C<PERL5_ITHREADS_STACK_SIZE>:
643 PERL5_ITHREADS_STACK_SIZE=1048576
644 export PERL5_ITHREADS_STACK_SIZE
645 perl -e'use threads; print(threads->get_stack_size(), "\n")'
647 This value overrides any C<stack_size> parameter given to C<use threads>. Its
648 primary purpose is to permit setting the per-thread stack size for legacy
649 threaded applications.
651 =item threads->create({'stack_size' => VALUE}, FUNCTION, ARGS)
653 The stack size an individual threads may also be specified. This may be done
654 by calling C<-E<gt>create()> with a parameter hash as the first argument:
656 my $thr = threads->create({'stack_size' => 32*4096}, \&foo, @args);
658 =item $thr2 = $thr1->create(FUNCTION, ARGS)
660 This creates a new thread (C<$thr2>) that inherits the stack size from an
661 existing thread (C<$thr1>). This is shorthand for the following:
663 my $stack_size = $thr1->get_stack_size();
664 my $thr2 = threads->create({'stack_size' => $stack_size}, FUNCTION, ARGS);
668 =head1 THREAD SIGNALLING
670 When safe signals is in effect (the default behavior - see L</"Unsafe signals">
671 for more details), then signals may be sent and acted upon by individual
676 =item $thr->kill('SIG...');
678 Sends the specified signal to the thread. Signal names and (positive) signal
679 numbers are the same as those supported by
680 L<kill()|perlfunc/"kill SIGNAL, LIST">. For example, 'SIGTERM', 'TERM' and
681 (depending on the OS) 15 are all valid arguments to C<-E<gt>kill()>.
683 Returns the thread object to allow for method chaining:
685 $thr->kill('SIG...')->join();
689 Signal handlers need to be set up in the threads for the signals they are
690 expected to act upon. Here's an example for I<cancelling> a thread:
696 # Thread 'cancellation' signal handler
697 $SIG{'KILL'} = sub { threads->exit(); };
703 my $thr = threads->create('thr_func');
707 # Signal the thread to terminate, and then detach
708 # it so that it will get cleaned up automatically
709 $thr->kill('KILL')->detach();
711 Here's another simplistic example that illustrates the use of thread
712 signalling in conjunction with a semaphore to provide rudimentary I<suspend>
713 and I<resume> capabilities:
716 use Thread::Semaphore;
722 # Thread 'suspend/resume' signal handler
724 $sema->down(); # Thread suspended
725 $sema->up(); # Thread resumes
731 # Create a semaphore and send it to a thread
732 my $sema = Thread::Semaphore->new();
733 my $thr = threads->create('thr_func', $sema);
741 # Allow the thread to continue
744 CAVEAT: The thread signalling capability provided by this module does not
745 actually send signals via the OS. It I<emulates> signals at the Perl-level
746 such that signal handlers are called in the appropriate thread. For example,
747 sending C<$thr-E<gt>kill('STOP')> does not actually suspend a thread (or the
748 whole process), but does cause a C<$SIG{'STOP'}> handler to be called in that
749 thread (as illustrated above).
751 As such, signals that would normally not be appropriate to use in the
752 C<kill()> command (e.g., C<kill('KILL', $$)>) are okay to use with the
753 C<-E<gt>kill()> method (again, as illustrated above).
755 Correspondingly, sending a signal to a thread does not disrupt the operation
756 the thread is currently working on: The signal will be acted upon after the
757 current operation has completed. For instance, if the thread is I<stuck> on
758 an I/O call, sending it a signal will not cause the I/O call to be interrupted
759 such that the signal is acted up immediately.
761 Sending a signal to a terminated thread is ignored.
767 =item Perl exited with active threads:
769 If the program exits without all threads having either been joined or
770 detached, then this warning will be issued.
772 NOTE: If the I<main> thread exits, then this warning cannot be suppressed
773 using C<no warnings 'threads';> as suggested below.
775 =item Thread creation failed: pthread_create returned #
777 See the appropriate I<man> page for C<pthread_create> to determine the actual
778 cause for the failure.
780 =item Thread # terminated abnormally: ...
782 A thread terminated in some manner other than just returning from its entry
783 point function. For example, the thread may have terminated using C<die>.
785 =item Using minimum thread stack size of #
787 Some platforms have a minimum thread stack size. Trying to set the stack size
788 below this value will result in the above warning, and the stack size will be
791 =item Thread creation failed: pthread_attr_setstacksize(I<SIZE>) returned 22
793 The specified I<SIZE> exceeds the system's maximum stack size. Use a smaller
794 value for the stack size.
798 If needed, thread warnings can be suppressed by using:
800 no warnings 'threads';
802 in the appropriate scope.
808 =item This Perl not built to support threads
810 The particular copy of Perl that you're trying to use was not built using the
811 C<useithreads> configuration option.
813 Having threads support requires all of Perl and all of the XS modules in the
814 Perl installation to be rebuilt; it is not just a question of adding the
815 L<threads> module (i.e., threaded and non-threaded Perls are binary
818 =item Cannot change stack size of an existing thread
820 The stack size of currently extant threads cannot be changed, therefore, the
821 following results in the above error:
823 $thr->set_stack_size($size);
825 =item Cannot signal threads without safe signals
827 Safe signals must be in effect to use the C<-E<gt>kill()> signalling method.
828 See L</"Unsafe signals"> for more details.
830 =item Unrecognized signal name: ...
832 The particular copy of Perl that you're trying to use does not support the
833 specified signal being used in a C<-E<gt>kill()> call.
841 =item Parent-child threads
843 On some platforms, it might not be possible to destroy I<parent> threads while
844 there are still existing I<child> threads.
846 =item Creating threads inside special blocks
848 Creating threads inside C<BEGIN>, C<CHECK> or C<INIT> blocks should not be
849 relied upon. Depending on the Perl version and the application code, results
850 may range from success, to (apparently harmless) warnings of leaked scalar, or
851 all the way up to crashing of the Perl interpreter.
855 Since Perl 5.8.0, signals have been made safer in Perl by postponing their
856 handling until the interpreter is in a I<safe> state. See
857 L<perl58delta/"Safe Signals"> and L<perlipc/"Deferred Signals (Safe Signals)">
860 Safe signals is the default behavior, and the old, immediate, unsafe
861 signalling behavior is only in effect in the following situations:
865 =item * Perl was been built with C<PERL_OLD_SIGNALS> (see C<perl -V>).
867 =item * The environment variable C<PERL_SIGNALS> is set to C<unsafe> (see L<perlrun/"PERL_SIGNALS">).
869 =item * The module L<Perl::Unsafe::Signals> is used.
873 If unsafe signals is in effect, then signal handling is not thread-safe, and
874 the C<-E<gt>kill()> signalling method cannot be used.
876 =item Returning closures from threads
878 Returning closures from threads should not be relied upon. Depending of the
879 Perl version and the application code, results may range from success, to
880 (apparently harmless) warnings of leaked scalar, or all the way up to crashing
881 of the Perl interpreter.
883 =item Perl Bugs and the CPAN Version of L<threads>
885 Support for threads extents beyond the code in this module (i.e.,
886 F<threads.pm> and F<threads.xs>), and into the Perl iterpreter itself. Older
887 versions of Perl contain bugs that may manifest themselves despite using the
888 latest version of L<threads> from CPAN. There is no workaround for this other
889 than upgrading to the lastest version of Perl.
891 (Before you consider posting a bug report, please consult, and possibly post a
892 message to the discussion forum to see if what you've encountered is a known
903 L<threads> Discussion Forum on CPAN:
904 L<http://www.cpanforum.com/dist/threads>
906 Annotated POD for L<threads>:
907 L<http://annocpan.org/~JDHEDDEN/threads-1.43/threads.pm>
909 L<threads::shared>, L<perlthrtut>
911 L<http://www.perl.com/pub/a/2002/06/11/threads.html> and
912 L<http://www.perl.com/pub/a/2002/09/04/threads.html>
914 Perl threads mailing list:
915 L<http://lists.cpan.org/showlist.cgi?name=iThreads>
917 Stack size discussion:
918 L<http://www.perlmonks.org/?node_id=532956>
922 Artur Bergman E<lt>sky AT crucially DOT netE<gt>
924 threads is released under the same license as Perl.
926 CPAN version produced by Jerry D. Hedden <jdhedden AT cpan DOT org>
928 =head1 ACKNOWLEDGEMENTS
930 Richard Soderberg E<lt>perl AT crystalflame DOT netE<gt> -
931 Helping me out tons, trying to find reasons for races and other weird bugs!
933 Simon Cozens E<lt>simon AT brecon DOT co DOT ukE<gt> -
934 Being there to answer zillions of annoying questions
936 Rocco Caputo E<lt>troc AT netrus DOT netE<gt>
938 Vipul Ved Prakash E<lt>mail AT vipul DOT netE<gt> -
939 Helping with debugging
941 Dean Arnold E<lt>darnold AT presicient DOT comE<gt> -