Jerry,

--- "Jerry D. Hedden" <[EMAIL PROTECTED]> wrote:

> The default behavior for exit() in threads can be changed in
> several ways:
>     Global change
>         use threads 'exit' => 'threads_only';
>         # or
>         use threads 'exit' => 'threads';
> 
>     At thread creation
>         threads->create({'exit' => 'thread_only'}, ...);
>         # or
>         threads->create({'exit' => 'thread'}, ...);
> 
>     After thread creation
>         threads->set_thread_exit_only();   # Inside a thread
>         # or
>         $thr->set_thread_exit_only();
> 
> When a thread dies, it issues a warning.  It the thread's
> warning handler subsequently issues an 'exit()', that exit
> will operate as per the above.
> 
> The exit status (i.e., exit(status)) is preserved and
> propogated to the shell.
> 
> Comments?  Should the exit-override functionality be
> scrapped?
> 
> 

What happens to global scope when a module that internally uses threads, like

     use threads 'exit' => 'thread';

is dynamically loaded during run-time?

An example script:
   use threads;
   threads->create({'exit' => 'thread_only'}, sub{
      sleep 5;
      print "Thread exiting...\n";
      exit(0);
   });
   threads->create(sub{sleep 30;});
   require MyModule if int(rand() * 10) >= 5;
   $_->join() foreach threads->list;

And the associated module:

   package MyModule;
   use threads 'exit' => 'thread';

This example indicates that exit() behavior would *dynamically* change for the
script during run-time, depending entirely on whether or not the module were
loaded (a 50/50 chance, in this simple case).

The example script expects thread exit() calls to just exit the current thread,
yet the loaded module enables process exit() for all threads.  This would cause
threads started specifically in the script to behave in ways the script author
did not intend, and that behavior is out of his control without having to
modify the module (which may or may not be possible, depending on the software
license or ownership of the module(s), etc.).

Thus, allowing exit() behavior to be changed on a per thread is definately a
good idea; however, allowing exit context changes (via "use") that affect the
entire runtime still seems like a dangerous idea, without constraints.

   What if "use threads 'exit' => 'thread';" could be restricted to threads
created within the namespace (i.e. package) of an executed function/method? 
And the only exception to this being if use threads 'exit' => 'threads';" were
called in the main:: namespace, exit() would be globally overridden for threads
across ALL packages (no matter how the packages used threads themselves)?

This way, module authors could use it as a nice shortcut; however, end script
writers/application developers could use it to control overall execution
behavior (overriding all loaded module behavior) if desired.

What do you think?

-Eric

Reply via email to