hkmaly / matfyz.cz wrote:
> As mentioned in #7917, Mutex.lock is not safe inside signal
> handler. As mentioned in #6416, neither is Thread.join. But
> there seem to be no documentation about what IS safe to do
> inside signal handler. In C, it is not safe to just modify
> variable inside signal handler without locking. Is it safe in
> ruby in case of 1) global variable 2) class variable 3) object
> variable 4) thread local variable, as in
> Thread.current['local_var'] ? Is there any other method of
> locking usable inside trap content?

Actually, in C it is safe to set variables with the
"sig_atomic_t" type without locking.  Atomic instructions (C11
or __sync_* in gcc) are also safe.  In fact, it is never safe to
use locking such as pthread_mutex_lock inside a signal handler.

I have limited experience with the following, but I believe
Thread.handle_interrupt in Ruby 2.0+ can be used for this:

  trap(:INT) do
    Thread.handle_interrupt(Interrupt => :never) do
      # anything goes
    end
  end

I often deal with legacy projects which still run on 1.9.3
(or even 1.8 :x), so I've done some wacky stuff:

  trap(:INT) do
    # fire-and-forget thread
    Thread.new { something_which_locks_a_mutex }
  end

But usually, I stick to the basic stuff which doesn't take
locks: IO#syswrite, or IO#write_nonblock where IO#sync=true.
Buffered I/O is not allowed since it takes locks, same with most
stdio stuff in C.  I also know that Array#<<, Hash#[]= are
alright at least in CRuby.  Thread#[]= is probably alright, too

For ruby, assigning local variables is fine, hooked variables
(some globals) might not be, and maybe all class+ivars are OK.
It may be Ruby implementation dependent, though...

> Note that while response in this issue would be useful it
> would be even better if it appeared in official ruby
> documentation, if there is any. I realize it is not directly
> bug but it's likely going to be cause of many bugs if the
> answer is "no" on any part of this and only people who
> understand ruby core can answer this.

Maybe we can mark functions with reentrancy and thread-safety
levels in our RDoc like some *nix manpages do.  Other Ruby
implementations would need to follow if CRuby defines it as
spec.

Right now my personal take is to read the source code of
the methods I use and look for things it does under-the-hood;
but it's probably not for everyone.

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>