Re: Thread#raise, Thread#kill, and timeout.rb are unsafe
In article <E1JaB7P-0000Zc-QP@x61.netlab.jp>,
Yukihiro Matsumoto <matz@ruby-lang.org> writes:
> Probably. Does anyone have any idea?
The problem is, where is safe point.
You said "just turning on flags to reserve exception, then
raise exception at the safe place, as MRI does."
Your "safe" is for interpreter. Ruby shouldn't SEGV, etc.
But Charles's "safe" is for application. acquired lock
should be released later, etc.
Your "safe" is not enough for application.
We need a mechanism to delay asynchronous exceptions until a
safe point.
trap is bad way to do it. trap is similar to Unix signal
handler. Unix signal handler makes it difficult to avoid
race conditions around blocking operations such as I/O.
With trap, applications need to re-implement the race
condition handling in Ruby level. It is very difficult if
it is possible.
It is preferable to have a way to declare safe points
directly.
The safe points vary according to applications. Even in a
application, different kinds of exceptions may have
different safe points.
For example, there are applications KeyboardInterrupt is
safe as you said. I think a filter, such as grep, is a kind
of the applications. It means that any points in the
applications are safe points.
Another example: movemail is a program to move mbox in a
mail spool. It needs to lock a mbox. Assume we implement
movemail in Ruby and the lock scheme is file lock. The lock
file is removed in ensure clause. But asynchronous
exception in the ensure block may cause to fail removing the
lock file. So the ensure block is not safe points.
Yet another example: Apache can be stopped with apachectl
"stop" and "graceful-stop". "stop" aborts open connections
but "graceful-stop" doesn't. Assume we implement a
threading http server with keep-alive and similar stopping
feature in Ruby. "stop" can be implemented by killing
threads for each connections by (dangerous) Thread.kill. It
means that any points in the threads are safe points.
"graceful-stop" need to wait the threads until they waits
requests. Since keep-alive is assumed, the threads
doesn't terminate after the first request on a connection.
This means the safe points are the request waiting points of
the threads.
I think the safe points declaration mechanism should able to
define safe points for each exception and easy to handle
blocking operations without race conditions.
--
Tanaka Akira
|