2011-01-27 21 views
1

私はInitOnceExecuteOnce WinAPI関数で例外安全性の問題があります。コールバック関数から例外がスローされるたびにデッドロックが発生します。コールバックはデータが正常に初期化されたかどうかを呼び出し側に伝えるブール値のフラグを返しますが、私がfalseを返すと、例外を元に戻すことはできません。私はこのように問題を解決しようとしました。InitOnceExecuteOnce例外安全性

try 
{ 
    InitOnceExecuteOnce(&flag, init_once_handler, &arguments, 0); 
} catch (...) 
{ 
    InitOnceInitialize(&flag); 
    throw; 
} 

私は関数から例外をキャッチするたびに、私は再び構造を初期化し、例外を再スローなので、フラグは初期状態であるように、他のスレッドは、初期化されないデータを検索します。ただし、他のスレッドが例外をキャッチして再びフラグを初期化する前に、同期オブジェクトの待機を開始したために、デッドロックが発生することがあります。その問題に対する解決策はありますか?

ありがとうございます。

答えて

5

期待していないコード(たとえば、Cコード、場合によってはWindows API)でC++例外を投げるべきではありません。代わりに、あなたのコールバックにエラーが発生した場合はfalseを返すようにしてください。返信に反映されます。InitOnceExecuteOnce

+0

これはユーザー定義関数です。保証はできません。それはコンテナ、アルゴリズムを使用するC++コードであり、すべてのステップで例外が発生する可能性があります。この関数の実行結果の問題を回避し、例外を呼び出し元に伝播したいのですが、デッドロックが発生します。おそらくそれを可能にする別のメカニズムがありますか? – axe

+1

@axe:そうであれば、そのコールバックを自分のものでラップし、コールバックは例外をキャッチしてfalseを返します。関数の引数を構造体にラップすることもできます。これにより、コールバックから例外に関する情報を返すことができます。 – Hasturkun

+0

私はすでにこれを行っていますが、私は例外を再現するpolymorphクラスを使って例外オブジェクトをラップしました(boost :: current_exceptionのようなものですが、ユーザ定義のクラスオブジェクトをスローすると、彼はstd :: runtime_error( "unknown exception")をキャッチします。十分に良いですが、より良いかもしれません。 – axe

関連する問題