[#41278] [BUG:1.9] BINARY should not be ASCII-compatible — Yugui <yugui@...>

WXVndWkbJEIkRyQ5ISMbKEIKCgo+IBskQiRHISIkKiQqJGAkTSQzJDMkXiRHJE41RE9AJEclKyVQ

15 messages 2010/05/11

[#41407] [Bug #3339] win32ole test failure — Usaku NAKAMURA <redmine@...>

Bug #3339: win32ole test failure

20 messages 2010/05/25
[#41411] Re: [Bug #3339] win32ole test failure — Masaki Suketa <masaki.suketa@...> 2010/05/25

助田です。

[#41412] Re: [Bug #3339] win32ole test failure — "U.Nakamura" <usa@...> 2010/05/25

こんにちは、なかむら(う)です。

[ruby-dev:41187] Re: [Feature #3251] allow to unlock mutex locked by another thread

From: Yusuke ENDOH <mame@...>
Date: 2010-05-06 11:20:19 UTC
List: ruby-dev #41187
遠藤です。

2010年5月6日20:02 Tanaka Akira <akr@fsij.org>:
> 2010年5月6日1:24 Yusuke Endoh <redmine@ruby-lang.org>:
>
>> 2 について、現状は Thread#raise には以下のような race が存在します。
>>
>>   t1: begin 節を実行している
>>   t2: t1.raise する
>>   t1: rescue/ensure 節の実行を開始する
>>   t3: t1.raise する
>>   t1: rescue/ensure 節が実行されないまま再度例外が発生する
>
>> これを、Thread#raise の前に Mutex#lock するというルールにすれば、
>> race を避けて使うことができるようになります。と思います。
>
> なにか後始末が必要な処理があるとします。
> たとえば、open したものは close しないといけないとして、
> 以下のコードを考えます。
>
>   begin
>      f = open(filename)
>   ensure
>      f.close
>   end
>
> ここで、open が終了した後、f に代入する前にコンテキストスイッチが起こると
> どうでしょうか。
> コンテキストスイッチの結果、他のスレッドが動いて、上記のコードを動かしている
> スレッドを raise したとします。
>
> そうすると、ensure 節が実行されるわけですが、close はできません。
> なんでかというと、open で生成した IO オブジェクトがどこにも
> 記録されていないからです。
>
> これは上記の Mutex#lock を使っても防げません。
> 一回しか Thread#raise していないからです。


Thread.raise を受け付けたらまずい期間は mutex をロックしておけ、という
ことで解決できないでしょうか。

  # Thread 1
  begin
    m.synchronize do
      f = open(filename)
    end
    # ...
  ensure
    f.close if f
    m.unlock
  end

  # Thread 2
  m.lock
  th.raise


>> # ちなみにこの race はシグナルにも存在します
>
> POSIX シグナルでは、受け付けたシグナルは signal handler 内でマスクされるので、
> handler 内で再度そのシグナルで割り込まれる、という心配はありません。

いえ、そういう心配ではないです。
Ctrl+C を連打した場合、ensure の実行開始直後でもう一回 Interrupt が
発生してしまうと、ensure 節の中身が実行されない可能性があるのでは
ないかという心配です。

# ちゃんとは確認してないのですが、ひょっとしたら何か対策されている?

SIGINT が Interrupt 例外に自動変換されるのが問題なので、trap(:INT) など
で自力で対策すれば問題なくなると思います。


ところで、Ruby レベルの trap が実行中にシグナルを受け取ったら、別の
trap を実行してしまうことが (ささださんによると) あるらしいのですが、
まずいですかね。

-- 
Yusuke Endoh <mame@tsg.ne.jp>

In This Thread