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 が返ってきて、上のコードだとメモリ破壊が発生する件 (Linux や Solaris だと発生しないっぽい)。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.
pthread_cond_destroy (www.opengroup.org)
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.
この解釈論、微妙すぎる。
というか自分が変な使い方し過ぎな気もする。さっさと違うモデルに移行しよう。
2008/01/11 追記: 現象の理解に差がないか確認してみたけど明確に「仕様に合致している」って教えてくれた。Apple++ てか、お時間使っていただいてありがとうございますという感じ。 (参照: http://lists.apple.com/archives/Darwin-dev/2008/Jan/msg00092.html)