Mac OS X の pthread_cond_destroy でハマった

Mac OS だと、

Thread A:
   pthread_cond_wait(cond, &mutex);
   while ((err = pthread_cond_destroy(cond)) != 0) {
       assert(err == EBUSY);
       usleep(1);
   }
   free(cond);

Thread B:
   // mutex is not locked
   pthread_cond_signal(cond);

みたいなコードで、pthread_cond_signal の実行が終わる前に pthread_cond_wait -> pthread_cond_destroy の呼出が発生した場合に EBUSY が返らず 0 が返ってきて、上のコードだとメモリ破壊が発生する件 (LinuxSolaris だと発生しないっぽい)。Darwin-dev ML でバグじゃないのと言ったPOSIX の仕様的にOKだって言われた><

The pthread_cond_destroy() function shall destroy the given condition variable specified by cond; the object becomes, in effect, uninitialized. An implementation may cause pthread_cond_destroy() to set the object referenced by cond to an invalid value. A destroyed condition variable object can be reinitialized using pthread_cond_init(); the results of otherwise referencing the object after it has been destroyed are undefined.


It shall be safe to destroy an initialized condition variable upon which no threads are currently blocked. Attempting to destroy a condition variable upon which other threads are currently blocked results in undefined behavior.

pthread_cond_destroy (www.opengroup.org)

 この解釈論、微妙すぎる。

 というか自分が変な使い方し過ぎな気もする。さっさと違うモデルに移行しよう。

2008/01/11 追記: 現象の理解に差がないか確認してみたけど明確に「仕様に合致している」って教えてくれた。Apple++ てか、お時間使っていただいてありがとうございますという感じ。 (参照: http://lists.apple.com/archives/Darwin-dev/2008/Jan/msg00092.html)