RE: [PATCH] threads 1.33
[p5sagit/p5-mst-13.2.git] / ext / threads / threads.pm
1 package threads;
2
3 use 5.008;
4
5 use strict;
6 use warnings;
7
8 our $VERSION = '1.33';
9 my $XS_VERSION = $VERSION;
10 $VERSION = eval $VERSION;
11
12
13 BEGIN {
14     # Verify this Perl supports threads
15     use Config;
16     if (! $Config{useithreads}) {
17         die("This Perl not built to support threads\n");
18     }
19
20     # Declare that we have been loaded
21     $threads::threads = 1;
22
23     # Complain if 'threads' is loaded after 'threads::shared'
24     if ($threads::shared::threads_shared) {
25         warn <<'_MSG_';
26 Warning, threads::shared has already been loaded.  To
27 enable shared variables, 'use threads' must be called
28 before threads::shared or any module that uses it.
29 _MSG_
30    }
31 }
32
33
34 # Load the XS code
35 require XSLoader;
36 XSLoader::load('threads', $XS_VERSION);
37
38
39 ### Export ###
40
41 sub import
42 {
43     my $class = shift;   # Not used
44
45     # Exported subroutines
46     my @EXPORT = qw(async);
47
48     # Handle args
49     while (my $sym = shift) {
50         if ($sym =~ /^stack/) {
51             threads->set_stack_size(shift);
52
53         } elsif ($sym =~ /all/) {
54             push(@EXPORT, qw(yield));
55
56         } else {
57             push(@EXPORT, $sym);
58         }
59     }
60
61     # Export subroutine names
62     my $caller = caller();
63     foreach my $sym (@EXPORT) {
64         no strict 'refs';
65         *{$caller.'::'.$sym} = \&{$sym};
66     }
67
68     # Set stack size via environment variable
69     if (exists($ENV{'PERL5_ITHREADS_STACK_SIZE'})) {
70         threads->set_stack_size($ENV{'PERL5_ITHREADS_STACK_SIZE'});
71     }
72 }
73
74
75 ### Methods, etc. ###
76
77 # Our own exit function/method
78 sub exit
79 {
80     CORE::exit(0);
81 }
82
83 # 'new' is an alias for 'create'
84 *new = \&create;
85
86 # 'async' is a function alias for the 'threads->create()' method
87 sub async (&;@)
88 {
89     unshift(@_, 'threads');
90     # Use "goto" trick to avoid pad problems from 5.8.1 (fixed in 5.8.2)
91     goto &create;
92 }
93
94 # Thread object equality checking
95 use overload (
96     '==' => \&equal,
97     '!=' => sub { ! equal(@_) },
98     'fallback' => 1
99 );
100
101 1;
102
103 __END__
104
105 =head1 NAME
106
107 threads - Perl interpreter-based threads
108
109 =head1 VERSION
110
111 This document describes threads version 1.33
112
113 =head1 SYNOPSIS
114
115     use threads ('yield', 'stack_size' => 64*4096);
116
117     sub start_thread {
118         my @args = @_;
119         print('Thread started: ', join(' ', @args), "\n");
120     }
121     my $thread = threads->create('start_thread', 'argument');
122     $thread->join();
123
124     threads->create(sub { print("I am a thread\n"); })->join();
125
126     my $thread3 = async { foreach (@files) { ... } };
127     $thread3->join();
128
129     # Invoke thread in list context (implicit) so it can return a list
130     my ($thr) = threads->create(sub { return (qw/a b c/); });
131     # or specify list context explicitly
132     my $thr = threads->create({'context' => 'list'},
133                               sub { return (qw/a b c/); });
134     my @results = $thr->join();
135
136     $thread->detach();
137
138     $thread = threads->self();
139     $thread = threads->object($tid);
140
141     $tid = threads->tid();
142     $tid = threads->self->tid();
143     $tid = $thread->tid();
144
145     threads->yield();
146     yield();
147
148     my @threads = threads->list();
149     my $thread_count = threads->list();
150
151     if ($thr1 == $thr2) {
152         ...
153     }
154
155     $stack_size = threads->get_stack_size();
156     $old_size = threads->set_stack_size(32*4096);
157
158     # Create a thread with a specific context and stack size
159     my $thr = threads->create({ 'context'    => 'list',
160                                 'stack_size' => 32*4096 },
161                               \&foo);
162     my @results = $thr->join();
163
164     $thr->kill('SIGUSR1');
165
166     threads->exit();
167
168 =head1 DESCRIPTION
169
170 Perl 5.6 introduced something called interpreter threads.  Interpreter threads
171 are different from I<5005threads> (the thread model of Perl 5.005) by creating
172 a new Perl interpreter per thread, and not sharing any data or state between
173 threads by default.
174
175 Prior to Perl 5.8, this has only been available to people embedding Perl, and
176 for emulating fork() on Windows.
177
178 The I<threads> API is loosely based on the old Thread.pm API. It is very
179 important to note that variables are not shared between threads, all variables
180 are by default thread local.  To use shared variables one must use
181 L<threads::shared>.
182
183 It is also important to note that you must enable threads by doing C<use
184 threads> as early as possible in the script itself, and that it is not
185 possible to enable threading inside an C<eval "">, C<do>, C<require>, or
186 C<use>.  In particular, if you are intending to share variables with
187 L<threads::shared>, you must C<use threads> before you C<use threads::shared>.
188 (C<threads> will emit a warning if you do it the other way around.)
189
190 =over
191
192 =item $thr = threads->create(FUNCTION, ARGS)
193
194 This will create a new thread that will begin execution with the specified
195 entry point function, and give it the I<ARGS> list as parameters.  It will
196 return the corresponding threads object, or C<undef> if thread creation failed.
197
198 I<FUNCTION> may either be the name of a function, an anonymous subroutine, or
199 a code ref.
200
201     my $thr = threads->create('func_name', ...);
202         # or
203     my $thr = threads->create(sub { ... }, ...);
204         # or
205     my $thr = threads->create(\&func, ...);
206
207 The C<-E<gt>new()> method is an alias for C<-E<gt>create()>.
208
209 =item $thr->join()
210
211 This will wait for the corresponding thread to complete its execution.  When
212 the thread finishes, C<-E<gt>join()> will return the return value(s) of the
213 entry point function.
214
215 The context (void, scalar or list) for the return value(s) for C<-E<gt>join()>
216 is determined at the time of thread creation.
217
218     # Create thread in list context (implicit)
219     my ($thr1) = threads->create(sub {
220                                     my @results = qw(a b c);
221                                     return (@results);
222                                  });
223     #   or (explicit)
224     my $thr1 = threads->create({'context' => 'list'},
225                                sub {
226                                     my @results = qw(a b c);
227                                     return (@results);
228                                });
229     # Retrieve list results from thread
230     my @res1 = $thr1->join();
231
232     # Create thread in scalar context (implicit)
233     my $thr2 = threads->create(sub {
234                                     my $result = 42;
235                                     return ($result);
236                                  });
237     # Retrieve scalar result from thread
238     my $res2 = $thr2->join();
239
240     # Create a thread in void context (explicit)
241     my $thr3 = threads->create({'void' => 1},
242                                sub { print("Hello, world\n"); });
243     # Join the thread in void context (i.e., no return value)
244     $thr3->join();
245
246 See L</"THREAD CONTEXT"> for more details.
247
248 If the program exits without all threads having either been joined or
249 detached, then a warning will be issued.
250
251 Calling C<-E<gt>join()> or C<-E<gt>detach()> on an already joined thread will
252 cause an error to be thrown.
253
254 =item $thr->detach()
255
256 Makes the thread unjoinable, and causes any eventual return value to be
257 discarded.  When the program exits, any detached threads that are still
258 running are silently terminated.
259
260 If the program exits without all threads having either been joined or
261 detached, then a warning will be issued.
262
263 Calling C<-E<gt>join()> or C<-E<gt>detach()> on an already detached thread
264 will cause an error to be thrown.
265
266 =item threads->detach()
267
268 Class method that allows a thread to detach itself.
269
270 =item threads->exit()
271
272 The usual method for terminating a thread is to
273 L<return()|perlfunc/"return EXPR"> from the entry point function with the
274 appropriate return value(s).
275
276 If needed, a thread can be exited at any time by calling
277 C<threads-E<gt>exit()>.  This will cause the thread to return C<undef> in a
278 scalar context, or the empty list in a list context.
279
280 Calling C<die()> in a thread indicates an abnormal exit for the thread.  Any
281 C<$SIG{__DIE__}> handler in the thread will be called first, and then the
282 thread will exit with a warning message that will contain any arguments passed
283 in the C<die()> call.
284
285 Calling C<exit()> in a thread is discouraged, but is equivalent to calling
286 C<threads-E<gt>exit()>.
287
288 If the desired affect is to truly terminate the application from a thread,
289 then use L<POSIX::_exit()|POSIX/"_exit">, if available.
290
291 =item threads->self()
292
293 Class method that allows a thread to obtain its own I<threads> object.
294
295 =item $thr->tid()
296
297 Returns the ID of the thread.  Thread IDs are unique integers with the main
298 thread in a program being 0, and incrementing by 1 for every thread created.
299
300 =item threads->tid()
301
302 Class method that allows a thread to obtain its own ID.
303
304 =item threads->object($tid)
305
306 This will return the I<threads> object for the I<active> thread associated
307 with the specified thread ID.  Returns C<undef> if there is no thread
308 associated with the TID, if the thread is joined or detached, if no TID is
309 specified or if the specified TID is undef.
310
311 =item threads->yield()
312
313 This is a suggestion to the OS to let this thread yield CPU time to other
314 threads.  What actually happens is highly dependent upon the underlying
315 thread implementation.
316
317 You may do C<use threads qw(yield)>, and then just use C<yield()> in your
318 code.
319
320 =item threads->list()
321
322 In a list context, returns a list of all non-joined, non-detached I<threads>
323 objects.  In a scalar context, returns a count of the same.
324
325 =item $thr1->equal($thr2)
326
327 Tests if two threads objects are the same thread or not.  This is overloaded
328 to the more natural forms:
329
330     if ($thr1 == $thr2) {
331         print("Threads are the same\n");
332     }
333     # or
334     if ($thr1 != $thr2) {
335         print("Threads differ\n");
336     }
337
338 (Thread comparison is based on thread IDs.)
339
340 =item async BLOCK;
341
342 C<async> creates a thread to execute the block immediately following
343 it.  This block is treated as an anonymous subroutine, and so must have a
344 semi-colon after the closing brace.  Like C<threads->create()>, C<async>
345 returns a I<threads> object.
346
347 =item $thr->_handle()
348
349 This I<private> method returns the memory location of the internal thread
350 structure associated with a threads object.  For Win32, this is a pointer to
351 the C<HANDLE> value returned by C<CreateThread> (i.e., C<HANDLE *>); for other
352 platforms, it is a pointer to the C<pthread_t> structure used in the
353 C<pthread_create> call (i.e., C<pthread_t *>).
354
355 This method is of no use for general Perl threads programming.  Its intent is
356 to provide other (XS-based) thread modules with the capability to access, and
357 possibly manipulate, the underlying thread structure associated with a Perl
358 thread.
359
360 =item threads->_handle()
361
362 Class method that allows a thread to obtain its own I<handle>.
363
364 =back
365
366 =head1 THREAD CONTEXT
367
368 As with subroutines, the type of value returned from a thread's entry point
369 function may be determined by the thread's I<context>:  list, scalar or void.
370 The thread's context is determined at thread creation.  This is necessary so
371 that the context is available to the entry point function via
372 L<wantarray()|perlfunc/"wantarray">.  The thread may then specify a value of
373 the appropriate type to be returned from C<-E<gt>join()>.
374
375 =head2 Explicit context
376
377 Because thread creation and thread joining may occur in different contexts, it
378 may be desirable to state the context explicitly to the thread's entry point
379 function.  This may be done by calling C<-E<gt>create()> with a parameter hash
380 as the first argument:
381
382     my $thr = threads->create({'context' => 'list'}, \&foo);
383     ...
384     my @results = $thr->join();
385
386 In the above, the threads object is returned to the parent thread in scalar
387 context, and the thread's entry point function C<foo> will be called in list
388 context such that the parent thread can receive a list from the C<-E<gt>join()>
389 call.  Similarly, if you need the threads object, but your thread will not be
390 returning a value (i.e., I<void> context), you would do the following:
391
392     my $thr = threads->create({'context' => 'void'}, \&foo);
393     ...
394     $thr->join();
395
396 The context type may also be used as the I<key> in the parameter hash followed
397 by a I<true> value:
398
399     threads->create({'scalar' => 1}, \&foo);
400     ...
401     my ($thr) = threads->list();
402     my $result = $thr->join();
403
404 =head2 Implicit context
405
406 If not explicitly stated, the thread's context is implied from the context
407 of the C<-E<gt>create()> call:
408
409     # Create thread in list context
410     my ($thr) = threads->create(...);
411
412     # Create thread in scalar context
413     my $thr = threads->create(...);
414
415     # Create thread in void context
416     threads->create(...);
417
418 =head1 THREAD STACK SIZE
419
420 The default per-thread stack size for different platforms varies
421 significantly, and is almost always far more than is needed for most
422 applications.  On Win32, Perl's makefile explicitly sets the default stack to
423 16 MB; on most other platforms, the system default is used, which again may be
424 much larger than is needed.
425
426 By tuning the stack size to more accurately reflect your application's needs,
427 you may significantly reduce your application's memory usage, and increase the
428 number of simultaneously running threads.
429
430 N.B., on Windows, Address space allocation granularity is 64 KB, therefore,
431 setting the stack smaller than that on Win32 Perl will not save any more
432 memory.
433
434 =over
435
436 =item threads->get_stack_size();
437
438 Returns the current default per-thread stack size.  The default is zero, which
439 means the system default stack size is currently in use.
440
441 =item $size = $thr->get_stack_size();
442
443 Returns the stack size for a particular thread.  A return value of zero
444 indicates the system default stack size was used for the thread.
445
446 =item $old_size = threads->set_stack_size($new_size);
447
448 Sets a new default per-thread stack size, and returns the previous setting.
449
450 Some platforms have a minimum thread stack size.  Trying to set the stack size
451 below this value will result in a warning, and the minimum stack size will be
452 used.
453
454 Some Linux platforms have a maximum stack size.  Setting too large of a stack
455 size will cause thread creation to fail.
456
457 If needed, C<$new_size> will be rounded up to the next multiple of the memory
458 page size (usually 4096 or 8192).
459
460 Threads created after the stack size is set will then either call
461 C<pthread_attr_setstacksize()> I<(for pthreads platforms)>, or supply the
462 stack size to C<CreateThread()> I<(for Win32 Perl)>.
463
464 (Obviously, this call does not affect any currently extant threads.)
465
466 =item use threads ('stack_size' => VALUE);
467
468 This sets the default per-thread stack size at the start of the application.
469
470 =item $ENV{'PERL5_ITHREADS_STACK_SIZE'}
471
472 The default per-thread stack size may be set at the start of the application
473 through the use of the environment variable C<PERL5_ITHREADS_STACK_SIZE>:
474
475     PERL5_ITHREADS_STACK_SIZE=1048576
476     export PERL5_ITHREADS_STACK_SIZE
477     perl -e'use threads; print(threads->get_stack_size(), "\n")'
478
479 This value overrides any C<stack_size> parameter given to C<use threads>.  Its
480 primary purpose is to permit setting the per-thread stack size for legacy
481 threaded applications.
482
483 =item threads->create({'stack_size' => VALUE}, FUNCTION, ARGS)
484
485 The stack size an individual threads may also be specified.  This may be done
486 by calling C<-E<gt>create()> with a parameter hash as the first argument:
487
488     my $thr = threads->create({'stack_size' => 32*4096}, \&foo, @args);
489
490 =item $thr2 = $thr1->create(FUNCTION, ARGS)
491
492 This creates a new thread (C<$thr2>) that inherits the stack size from an
493 existing thread (C<$thr1>).  This is shorthand for the following:
494
495     my $stack_size = $thr1->get_stack_size();
496     my $thr2 = threads->create({'stack_size' => $stack_size}, FUNCTION, ARGS);
497
498 =back
499
500 =head1 THREAD SIGNALLING
501
502 When safe signals is in effect (the default behavior - see L</"Unsafe signals">
503 for more details), then signals may be sent and acted upon by individual
504 threads.
505
506 =over 4
507
508 =item $thr->kill('SIG...');
509
510 Sends the specified signal to the thread.  Signal names and (positive) signal
511 numbers are the same as those supported by
512 L<kill()|perlfunc/"kill SIGNAL, LIST">.  For example, 'SIGTERM', 'TERM' and
513 (depending on the OS) 15 are all valid arguments to C<-E<gt>kill()>.
514
515 Returns the thread object to allow for method chaining:
516
517     $thr->kill('SIG...')->join();
518
519 =back
520
521 Signal handlers need to be set up in the threads for the signals they are
522 expected to act upon.  Here's an example for I<cancelling> a thread:
523
524     use threads;
525
526     # Suppress warning message when thread is 'killed'
527     no warnings 'threads';
528
529     sub thr_func
530     {
531         # Thread 'cancellation' signal handler
532         $SIG{'KILL'} = sub { die("Thread killed\n"); };
533
534         ...
535     }
536
537     # Create a thread
538     my $thr = threads->create('thr_func');
539
540     ...
541
542     # Signal the thread to terminate, and then detach
543     # it so that it will get cleaned up automatically
544     $thr->kill('KILL')->detach();
545
546 Here's another simplistic example that illustrates the use of thread
547 signalling in conjunction with a semaphore to provide rudimentary I<suspend>
548 and I<resume> capabilities:
549
550     use threads;
551     use Thread::Semaphore;
552
553     sub thr_func
554     {
555         my $sema = shift;
556
557         # Thread 'suspend/resume' signal handler
558         $SIG{'STOP'} = sub {
559             $sema->down();      # Thread suspended
560             $sema->up();        # Thread resumes
561         };
562
563         ...
564     }
565
566     # Create a semaphore and send it to a thread
567     my $sema = Thread::Semaphore->new();
568     my $thr = threads->create('thr_func', $sema);
569
570     # Suspend the thread
571     $sema->down();
572     $thr->kill('STOP');
573
574     ...
575
576     # Allow the thread to continue
577     $sema->up();
578
579 CAVEAT:  The thread signalling capability provided by this module does not
580 actually send signals via the OS.  It I<emulates> signals at the Perl-level
581 such that signal handlers are called in the appropriate thread.  For example,
582 sending C<$thr-E<gt>kill('STOP')> does not actually suspend a thread (or the
583 whole process), but does cause a C<$SIG{'STOP'}> handler to be called in that
584 thread (as illustrated above).
585
586 As such, signals that would normally not be appropriate to use in the
587 C<kill()> command (e.g., C<kill('KILL', $$)>) are okay to use with the
588 C<-E<gt>kill()> method (again, as illustrated above).
589
590 Correspondingly, sending a signal to a thread does not disrupt the operation
591 the thread is currently working on:  The signal will be acted upon after the
592 current operation has completed.  For instance, if the thread is I<stuck> on
593 an I/O call, sending it a signal will not cause the I/O call to be interrupted
594 such that the signal is acted up immediately.
595
596 =head1 WARNINGS
597
598 =over 4
599
600 =item Perl exited with active threads:
601
602 If the program exits without all threads having either been joined or
603 detached, then this warning will be issued.
604
605 NOTE:  This warning cannot be suppressed using C<no warnings 'threads';> as
606 suggested below.
607
608 =item Thread creation failed: pthread_create returned #
609
610 See the appropriate I<man> page for C<pthread_create> to determine the actual
611 cause for the failure.
612
613 =item Thread # terminated abnormally: ...
614
615 A thread terminated in some manner other than just returning from its entry
616 point function.  For example, the thread may have terminated using C<die>.
617
618 =item Using minimum thread stack size of #
619
620 Some platforms have a minimum thread stack size.  Trying to set the stack size
621 below this value will result in the above warning, and the stack size will be
622 set to the minimum.
623
624 =item Thread creation failed: pthread_attr_setstacksize(I<SIZE>) returned 22
625
626 The specified I<SIZE> exceeds the system's maximum stack size.  Use a smaller
627 value for the stack size.
628
629 =back
630
631 If needed, thread warnings can be suppressed by using:
632
633     no warnings 'threads';
634
635 in the appropriate scope.
636
637 =head1 ERRORS
638
639 =over 4
640
641 =item This Perl not built to support threads
642
643 The particular copy of Perl that you're trying to use was not built using the
644 C<useithreads> configuration option.
645
646 Having threads support requires all of Perl and all of the XS modules in the
647 Perl installation to be rebuilt; it is not just a question of adding the
648 L<threads> module (i.e., threaded and non-threaded Perls are binary
649 incompatible.)
650
651 =item Cannot change stack size of an existing thread
652
653 The stack size of currently extant threads cannot be changed, therefore, the
654 following results in the above error:
655
656     $thr->set_stack_size($size);
657
658 =item Cannot signal threads without safe signals
659
660 Safe signals must be in effect to use the C<-E<gt>kill()> signalling method.
661 See L</"Unsafe signals"> for more details.
662
663 =item Unrecognized signal name: ...
664
665 The particular copy of Perl that you're trying to use does not support the
666 specified signal being used in a C<-E<gt>kill()> call.
667
668 =back
669
670 =head1 BUGS
671
672 =over
673
674 =item Parent-child threads
675
676 On some platforms, it might not be possible to destroy I<parent> threads while
677 there are still existing I<child> threads.
678
679 =item Creating threads inside special blocks
680
681 Creating threads inside C<BEGIN>, C<CHECK> or C<INIT> blocks should not be
682 relied upon.  Depending on the Perl version and the application code, results
683 may range from success, to (apparently harmless) warnings of leaked scalar, or
684 all the way up to crashing of the Perl interpreter.
685
686 =item Unsafe signals
687
688 Since Perl 5.8.0, signals have been made safer in Perl by postponing their
689 handling until the interpreter is in a I<safe> state.  See
690 L<perl58delta/"Safe Signals"> and L<perlipc/"Deferred Signals (Safe Signals)">
691 for more details.
692
693 Safe signals is the default behavior, and the old, immediate, unsafe
694 signalling behavior is only in effect in the following situations:
695
696 =over 4
697
698 =item * Perl was been built with C<PERL_OLD_SIGNALS> (see C<perl -V>).
699
700 =item * The environment variable C<PERL_SIGNALS> is set to C<unsafe> (see L<perlrun/"PERL_SIGNALS">).
701
702 =item * The module L<Perl::Unsafe::Signals> is used.
703
704 =back
705
706 If unsafe signals is in effect, then signal handling is not thread-safe, and
707 the C<-E<gt>kill()> signalling method cannot be used.
708
709 =item Returning closures from threads
710
711 Returning closures from threads should not be relied upon.  Depending of the
712 Perl version and the application code, results may range from success, to
713 (apparently harmless) warnings of leaked scalar, or all the way up to crashing
714 of the Perl interpreter.
715
716 =item Perl Bugs and the CPAN Version of L<threads>
717
718 Support for threads extents beyond the code in this module (i.e.,
719 F<threads.pm> and F<threads.xs>), and into the Perl iterpreter itself.  Older
720 versions of Perl contain bugs that may manifest themselves despite using the
721 latest version of L<threads> from CPAN.  There is no workaround for this other
722 than upgrading to the lastest version of Perl.
723
724 (Before you consider posting a bug report, please consult, and possibly post a
725 message to the discussion forum to see if what you've encountered is a known
726 problem.)
727
728 =back
729
730 =head1 REQUIREMENTS
731
732 Perl 5.8.0 or later
733
734 =head1 SEE ALSO
735
736 L<threads> Discussion Forum on CPAN:
737 L<http://www.cpanforum.com/dist/threads>
738
739 Annotated POD for L<threads>:
740 L<http://annocpan.org/~JDHEDDEN/threads-1.33/threads.pm>
741
742 L<threads::shared>, L<perlthrtut>
743
744 L<http://www.perl.com/pub/a/2002/06/11/threads.html> and
745 L<http://www.perl.com/pub/a/2002/09/04/threads.html>
746
747 Perl threads mailing list:
748 L<http://lists.cpan.org/showlist.cgi?name=iThreads>
749
750 Stack size discussion:
751 L<http://www.perlmonks.org/?node_id=532956>
752
753 =head1 AUTHOR
754
755 Artur Bergman E<lt>sky AT crucially DOT netE<gt>
756
757 threads is released under the same license as Perl.
758
759 CPAN version produced by Jerry D. Hedden <jdhedden AT cpan DOT org>
760
761 =head1 ACKNOWLEDGEMENTS
762
763 Richard Soderberg E<lt>perl AT crystalflame DOT netE<gt> -
764 Helping me out tons, trying to find reasons for races and other weird bugs!
765
766 Simon Cozens E<lt>simon AT brecon DOT co DOT ukE<gt> -
767 Being there to answer zillions of annoying questions
768
769 Rocco Caputo E<lt>troc AT netrus DOT netE<gt>
770
771 Vipul Ved Prakash E<lt>mail AT vipul DOT netE<gt> -
772 Helping with debugging
773
774 Dean Arnold E<lt>darnold AT presicient DOT comE<gt> -
775 Stack size API
776
777 =cut