localtimeやstrtokは本当にスレッドセーフにできないのか (1)

googleから私の日記に、localtime_r や strtok_r, getpwnam_r などのキーワードで飛んでくる方が結構多いので、ちょっと関連する話題を書いてみます(内容の割に長い…)。


さて、8/9の日記で、POSIXのlocaltimeという関数(下記)を取り上げ、

struct tm *localtime(const time_t *timer);

この関数を複数のスレッドが同時に使うと処理が破綻すると書きました。また、この関数はシグネチャが腐っているので、libcの外側でmutexを使っても処理の破綻を回避することはできず、localtime_rという代用関数を使うしかないとも書きました。POSIXで示されている代用関数(TSF)の一覧は、8/21の日記に書いた通りです。


本日は視点をちょっと変えてみて、「localtimeのシグネチャは本当にダメダメなのか?」に焦点を当てて考えてみることにします。もし、シグネチャを変えずにlocaltimeをスレッドセーフに実装する手段があるなら、次のことができて嬉しいからです。

LD_PRELOADを用いて、libcのlocaltime関数を、自作のもので置換してしまう。すると、誤ってlocaltime関数を使ってしまっている既存のマルチスレッドプログラムを、書き換え無しで安全にできる。


結論を先に書くと、そういう方法は、ややトリッキーながら存在すると思います。
方法は続きの記事で。