[#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:41184] Re: [Feature #3251] allow to unlock mutex locked by another thread

From: Tanaka Akira <akr@...>
Date: 2010-05-06 11:02:33 UTC
List: ruby-dev #41184
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 していないからです。

というわけで、rescue/ensure 節の中で他から raise されるのをどうにかすれば
Thread#raise が安全になる、というわけではありません。

> # ちなみにこの race はシグナルにも存在します

POSIX シグナルでは、受け付けたシグナルは signal handler 内でマスクされるので、
handler 内で再度そのシグナルで割り込まれる、という心配はありません。

昔話としてはそうではなかったものもあったようで、その race の話は
検索すれば出てくるかもしれません。
-- 
[田中 哲][たなか あきら][Tanaka Akira]

In This Thread