Darwinのスレッドキャンセルポイント

Darwin(OSX)でHamigaki.Coroutineが動かない件を調査しました。
Darwinには<ucontext.h>ヘッダは存在するものの、getcontext()等の関数はないため、(とりあえずは)pthreadによるエミュレーションモードを使うことになります。
で、そのpthread版が動かなかったわけですが、原因はスレッドのキャンセルが動いていないことにありました。
POSIX規格ではpthread_cond_wait()はスレッドのキャンセルポイントになっていて、この関数の呼び出しでブロック中に他のスレッドからpthread_cancel()を呼ぶことでスレッドをキャンセルすることができます。
しかし、Darwinではpthread_cond_wait()はキャンセルポイントではありません。
どうもpthread_testcancel()等ごく一部の関数しかキャンセルポイントになっていないようです。
しかたがないので、pthread_cond_wait()の直後にpthread_testcancel()を追加して、キャンセルする側でもpthread_cancel()の後でpthread_cond_signal()してブロックを解除するようにしました。
今日の差分
機会があればスレッドによるエミュレーションではなく、本物のコルーチンも実装したいと思います。