ポイゾニング

全てのアンセーフな型は最低限の例外安全性を満たしていることが必要ですが、全ての アンセーフな型が最大限の例外安全性を満たしている必要はありません。 仮に型自体が満たしていたとしても、実装が別の意味を暗黙に付与してしまう場合も あります。例えば整数型は間違いなく例外安全ですが、その(訳注: 最大限の例外安全性 を担保する)セマンティクスを独自に持つわけではないため、整数をアップデートする 際にパニックを起こすと、プログラムが一貫性のない状態に陥る可能性があります。

これは通常は問題になることはありません。というのも例外を発見した処理は直後に 死ぬためです。例えばVecを別のスレッドに送り、そのスレッドがパニックし、結果として Vecが奇妙な状態に陥ったとしても、ドロップされて永久に闇の彼方に葬られてしまうためです。 とはいえ型によってはパニックの境界をまたいでくる場合もあります。

こういった型は、パニックに直面した際に、意図的に自分自身をポイゾンする可能性があり ます。ポイゾニング自体は特に何か別の事態を引き起こすわけではありません。一般的に 通常の手続きの継続を止めるべきであることを表しています。よく知られた例として 標準ライブラリのMutex型があります。この型は対応するMutexGuards(ロックを取得した際に 返るもの)が、パニックによってドロップされた際に自分自身をポイゾンします。以後Mutexをロック しようとするとErrを返すかパニックします。

Mutexのポイゾンは、通常の文脈で語られるRustの安全性とは異なる用途のためのものです。 Mutexを扱うスレッドがロック中にパニックを引き起こした場合、Mutexの中のデータは変更中 であった可能性が高く、一貫性を欠いていたり変更が未完了の状態であったりするため、 そのようなデータを盲目的に扱う危険性に対する安全装置として動作します。 注意しておきたいのはそのような型が適切に実装されていた場合、メモリ安全性確実 に満たしているという点です。つまるところ、最低限の例外安全性は満たしていなくては ならないということです。

しかしながら、Mutexが例えばBinaryHeapを持っていたとして、その値が実際にはヒープ として要件を満たさなかったような場合、そのデータ構造を利用するプログラムが作成者の 意図通りの挙動をするということは考えにくいです。通常とは異なる振る舞いをする でしょう。とはいえ、十分に注意すればそのような場合でもその値が何かに使える 可能性はあります。安全ではあるのです。ただ、ナンセンスかもしれませんが。

関連キーワード:  ポイゾニング, Mutex, パニック, 例外, 通常, 実装, ライフタイム, ロック, 状態, Vec