From: Charles Oliver Nutter Date: 2008-03-22T15:02:37+09:00 Subject: Re: Thread#raise, Thread#kill, and timeout.rb are unsafe Tanaka Akira wrote: > Basically, asynchronous events should be queued. > > * make a queue for each thread. > * Thread#raise(exc) enqueue exc to the queue. > * Thread.check_interrupt(klass) checks an exception which is > a kind of klass in the queue of the current thread. If it > exists, the exception is raised. > * other queue examining mechanism, such as sigpending, etc, > may be useful. > > Thread.check_interrupt is a safe point. Agreed. This is essentially how these unsafe operations are implemented in JRuby currently. The "raise queue" is one-element long, and appropriate locks are acquired to modify it from outside the target thread. All threads periodically check to see if they've been "raised" or "killed" or whether they should sleep because another thread has "gone critical". The checkpoints are currently at the same points during execution that Ruby 1.8 checks whether it should run the thread scheduler. > However safe points is not only Thread.check_interrupt. > Blocking operations, such as I/O, may or may not be safe > points. It is because Thread.check_interrupt with blocking > operations causes race conditions. So application must > choose that make a blocking operation interruption safe or > uninterruptible. > > * Thread.blocking_interruptible(klass) { ... } > * Thread.blocking_uninterruptible(klass) { ... } Also good. Awful names though :) > Blocking operations in Thread.blocking_interruptible are > safe points. > > If a thread has no resources to release, it is safe to kill > asynchronously. Other than that, safe points should be > declared explicitly. When a resource is acquired, > application should declare it. > > * Thread.delay_interrupt(klass) { ... } > > It is safe points that out of outermost > Thread.delay_interrupt. > > Another idea is about ensure clause. Since an ensure > clause is used to release a resource, it may delay > asynchronous events as in Thread.delay_interrupt. As mental has said, if threads are uninterruptible by default, this would make ensures safe. I think that's the only reasonable option. - Charlie