[Ironruby-core] Code Review: Thread#raise
Charles Oliver Nutter
charles.nutter at sun.com
Wed Jan 7 08:12:12 EST 2009
I think I'm coming around to your side. My position is current the
following:
1. If critical officially remains specified as its current behavior in
MRI, we should be warning people not to use it and should have a warning
emitted at least once.
2. If we can get ruby-core to agree that critical should be expected to
be no more than a global mutex and not necessarily deschedule threads,
I'd be willing to make the same change in JRuby and omit the warning.
I definitely think we need to talk to ruby-core and open it up to the
community, however, to see if there are cases where people depend on
critical= actually descheduling. Shri: can you propose making the
"global mutex" definition of critical the official one?
- Charlie
Shri Borde wrote:
> I agree that critical= can cause problems, and should go away. However, it can also be used in a reasonably safe way. Something like this. Such usages do not rely on other threads being frozen. Most uses seem to use such a pattern.
>
> def get_unique_cookie()
> begin
> Thread.critical = true
> cookie = @@counter
> @@counter += 1
> ensure
> Thread.critical = false
> end
> cookie
> end
>
> I am suggesting not adding a warning purely from a pragmatic perspective. The patter above is used in a lots of of places, and a warning could irritate users if they see it too often when using their favorite gems.
>
> Is there a way for Ruby devs to control the warning level? If so, it will be a question of what level to put the warning under, not whether to add it or not.
>
> Thanks,
> Shri
>
>
> -----Original Message-----
> From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Charles Oliver Nutter
> Sent: Tuesday, January 06, 2009 10:53 AM
> To: ironruby-core at rubyforge.org
> Cc: IronRuby External Code Reviewers; Tomas Matousek
> Subject: Re: [Ironruby-core] Code Review: Thread#raise
>
> I think the implications of critical= in MRI are more complicated than
> just a local lock. It actually stops normal thread scheduling, so other
> threads freeze what they're doing. That's vastly more intrusive than
> just a lock or critical section:
>
> ◆ ruby -e "Thread.new { sleep 1; puts Time.now; redo }; sleep 3;
> Thread.critical = true; puts 'critical'; sleep 3; puts 'leaving
> critical'; Thread.critical = false; sleep 3"
> Tue Jan 06 18:50:34 +0000 2009
> Tue Jan 06 18:50:35 +0000 2009
> critical
> leaving critical
> Tue Jan 06 18:50:39 +0000 2009
> Tue Jan 06 18:50:40 +0000 2009
> Tue Jan 06 18:50:41 +0000 2009
>
> If those other threads are holding locks or resources, deadlock is
> extremely easy, and of course it's nearly impossible to emulate right
> with real parallel threads since you can't easily stop them whenever you
> want.
>
> #kill and #raise are also very tricky and dangerous, but they're at
> least localized. They can be defined in terms of a message passed from
> one thread to another plus a periodic message checkpoint.
>
> I still believe critical= is much more in need of a warning.
>
> Shri Borde wrote:
>> Warning sounds reasonable for Thread#kill and Thread#raise. FWIW, Mongrel and webbrick do use Thread#kill to kill a background thread.
>>
>> Thread.critical= can actually be used in a sane way for simple synchronization, like the lock keyword in C#. This is used much more widely, and a warning for this will cause lot of false alarms.
>>
>> Thanks,
>> Shri
>>
>>
>> -----Original Message-----
>> From: Tomas Matousek
>> Sent: Saturday, January 03, 2009 11:52 AM
>> To: Curt Hagenlocher; Shri Borde; IronRuby External Code Reviewers
>> Cc: ironruby-core at rubyforge.org
>> Subject: RE: Code Review: Thread#raise
>>
>> I think we should at least report a warning when Thread#kill, Thread#raise or Thread#critical= is called if not eliminating them as Charlie proposed on his blog.
>>
>> Tomas
>>
>> -----Original Message-----
>> From: Curt Hagenlocher
>> Sent: Tuesday, December 30, 2008 10:05 PM
>> To: Shri Borde; IronRuby External Code Reviewers
>> Cc: ironruby-core at rubyforge.org
>> Subject: RE: Code Review: Thread#raise
>>
>> Shouldn't the option "UseThreadAbortForSyncRaise" be called "...ForASyncRaise"?
>> I think that Thread.raise with no arguments should just inject a RuntimeError with no message as if $! were nil; this makes more sense than failing. Trying to reference a "current exception" in another thread is a scary operation even if that's what MRI is doing.
>>
>> Other than that, changes look really nice. But anyone thinking of using this functionality should read Charlie's excellent piece from earlier in the year: http://blog.headius.com/2008/02/rubys-threadraise-threadkill-timeoutrb.html
>>
>> -----Original Message-----
>> From: Shri Borde
>> Sent: Monday, December 29, 2008 3:00 PM
>> To: IronRuby External Code Reviewers
>> Cc: ironruby-core at rubyforge.org
>> Subject: Code Review: Thread#raise
>>
>> tfpt review "/shelveset:raise;REDMOND\sborde"
>> Comment :
>> Implements Thread#raise using Thread.Abort, and added tests for it
>> Implemented stress mode (RubyOptions.UseThreadAbortForSyncRaise) which found more issues. Fixed most but not all
>> Enabled test for timeout as well
>> Remaining work (not high pri for now)
>> - Thread#raise without Exception parameters is not supported as it needs to access the active exception of the target thread. This is stored as a thread-local static, and so cannot be accessed from other threads. Can be fixed by not using ThreadStaticAttribute.
>> - Adding probes (in generated code, in C# library code, etc) will help to raise the exception quicker as Thread.Abort can be delayed indefinitely. Ideally, we need both approaches. For now, using Thread.Abort goes a long way.
>> - Ideally, we would add a try-catch to the IDynamicObject/MetaObject code paths so that when other languages called into Ruby code, they would get the expected user exception rather than a ThreadAbortException
>>
>> RunRSpec: supports -ruby to run with MRI. Its much faster than doing "rake ruby why_regression". Added support for -e to run a specific example
>>
>>
>> _______________________________________________
>> Ironruby-core mailing list
>> Ironruby-core at rubyforge.org
>> http://rubyforge.org/mailman/listinfo/ironruby-core
>
> _______________________________________________
> Ironruby-core mailing list
> Ironruby-core at rubyforge.org
> http://rubyforge.org/mailman/listinfo/ironruby-core
> _______________________________________________
> Ironruby-core mailing list
> Ironruby-core at rubyforge.org
> http://rubyforge.org/mailman/listinfo/ironruby-core
More information about the Ironruby-core
mailing list