私はInitOnceExecuteOnce WinAPI関数で例外安全性の問題があります。コールバック関数から例外がスローされるたびにデッドロックが発生します。コールバックはデータが正常に初期化されたかどうかを呼び出し側に伝えるブール値のフラグを返しますが、私がfalseを返すと、例外を元に戻すことはできません。私はこのように問題を解決しようとしました。InitOnceExecuteOnce例外安全性
try
{
InitOnceExecuteOnce(&flag, init_once_handler, &arguments, 0);
} catch (...)
{
InitOnceInitialize(&flag);
throw;
}
私は関数から例外をキャッチするたびに、私は再び構造を初期化し、例外を再スローなので、フラグは初期状態であるように、他のスレッドは、初期化されないデータを検索します。ただし、他のスレッドが例外をキャッチして再びフラグを初期化する前に、同期オブジェクトの待機を開始したために、デッドロックが発生することがあります。その問題に対する解決策はありますか?
ありがとうございます。
これはユーザー定義関数です。保証はできません。それはコンテナ、アルゴリズムを使用するC++コードであり、すべてのステップで例外が発生する可能性があります。この関数の実行結果の問題を回避し、例外を呼び出し元に伝播したいのですが、デッドロックが発生します。おそらくそれを可能にする別のメカニズムがありますか? – axe
@axe:そうであれば、そのコールバックを自分のものでラップし、コールバックは例外をキャッチしてfalseを返します。関数の引数を構造体にラップすることもできます。これにより、コールバックから例外に関する情報を返すことができます。 – Hasturkun
私はすでにこれを行っていますが、私は例外を再現するpolymorphクラスを使って例外オブジェクトをラップしました(boost :: current_exceptionのようなものですが、ユーザ定義のクラスオブジェクトをスローすると、彼はstd :: runtime_error( "unknown exception")をキャッチします。十分に良いですが、より良いかもしれません。 – axe