CShareData::InitShareData はアプリケーション実行の初期に実行され、プロセスの死活を決める重要な関数ですが、共有メモリに定数を埋める退屈なコードにまみれて見通しが良くありません。添付のパッチは以下の変更から成っています。
- コンストラクタと InitShareData に分散していた CShareData のメンバ変数の初期化をコンストラクタの初期化リストで行います。初期値は NULL か 0 ですので何も起こりません。
- 共有メモリに初期定数を埋めるコードを CShareData::InitShareData から切り出して CShareData::InitDllShareData という名前の static メンバ関数にしました。DLLSHAREDATA だけではなく CShareData のコントロールプロセス限定メンバ変数の初期化も行っていた InitTypeConfigs 関数の呼び出しだけは this ポインタが必要なため、InitDllShareData に先駆けて InitShareData から直接呼び出していますが、それ以外は完全なコピペ関数とその呼び出しによる置き換えですので、間違いの入る余地はありません。
- this ポインタを必要としていなかった初期化関数(Init~)に static を付けました。
- InitShareData の残された部分に二重初期化を検出する assert を追加しました。
- InitShareData にあった If と else の両方に共通していたコードをひとつにしました。
InitShareData 以外の部分の変更点は static を付け加えたり、あやまってメンバ変数を参照してしまっていたのであろう部分の m_ を削ったりという些細なものです。InitShareData の中身は一本道になりましたのでパッチをあてた後のコードをなぞってみてください。簡単です。
このパッチは [patchunicode:#1116] がコミットできればコンフリクト解消の上でコミットしたいと考えています。
その次には CShareData の誤ったシングルトン化を元に戻し、env/CShareData.h の「@brief 共有データの管理」というコメントにそった状態を回復したいと考えています。それにより現在 GetDllShareData 関数が行っているような、InitShareData が呼ばれていない未初期化状態での CShareData へのアクセスを検知して拒絶することができるようになります。