たとえば、アプリケーションがキャンセル ポイントでブロックされ、read
シグナルが受信され、シグナル ハンドラが呼び出されたとします。Glibc/NPTL は、syscall の実行中に非同期キャンセルを有効にすることでキャンセル ポイントを実装しているため、私が知る限り、非同期キャンセルはシグナル ハンドラーの実行中に有効なままになります。もちろん、これはひどく間違っています。非同期キャンセルセーフではないが、シグナルハンドラーから安全に呼び出す必要がある関数がたくさんあるからです。
これにより、2 つの質問が残ります。
- 私は間違っていますか、それとも glibc/NPTL の動作は本当に危険なほど壊れているのでしょうか? もしそうなら、そのような危険な行動は準拠していますか?
- POSIX によると、プロセスがキャンセル ポイントである関数を実行しているときにシグナル ハンドラが呼び出された場合、どうなるでしょうか。
編集:pthread_cancel
潜在的なターゲットであるスレッドは、キャンセルポイントである関数がそのスレッドのコンテキストでシグナルハンドラーから呼び出されないようにする必要があることをほぼ確信しています:
一方では、キャンセルされる可能性があり、async-cancel-unsafe 関数を使用するスレッドで呼び出すことができるシグナル ハンドラーは、キャンセル ポイントである関数を呼び出す前にキャンセルを無効にする必要があります。これは、シグナルによって割り込まれたコードの観点からは、そのようなキャンセルは非同期キャンセルと同等であるためです。一方、シグナル ハンドラーは、非同期シグナル セーフではないため、シグナル ハンドラーが呼び出されたときに実行されるコードが非同期シグナル セーフ関数のみを使用しない限り、取り消しを無効にすることはできませpthread_setcancelstate
ん。