シャットダウンパズル

http://d.hatena.ne.jp/egggarden/20090201/1233471243
わからんので原文のコメント欄を読んだらようやく理解できた。

  1. DLL_PROCESS_DETACHは、ExitProcessの呼び出しにより発生する。
  2. ExitProcessを発行すると、ExitProcess(DLL_PROCESS_DETACHの呼び出しを含む)を処理するスレッド以外の全てのスレッドが強制終了する。
  3. そのため、(CleanUpStuffなどの)別のスレッドの終了処理は呼び出されない。
  4. 従ってDLL_PROCESS_DETACHにて、イベントオブジェクトに対してWaitForSingleObjectを発行するとロックしてしまうが、スレッドハンドルに対してWaitForSingleObjectを発行すると(スレッドはすでに終了しているため)すぐに制御が戻る。

ということらしい。

ところで、スレッドを(CreateThreadや_beginthreadexではなく)_beginthreadで作成していると、スレッド終了でハンドルが閉じてしまうので、(_beginthreadの戻り値で得られたハンドルに対して)WaitForSingleObjectを発行すると失敗する(戻り値がWAIT_FAILEDとなり、GetLastErrorがERROR_INVALID_HANDLEを返す)。この場合でも制御が戻るので顧客はラッキーではあるが、レアケースとして、もしも閉じたハンドルが(スレッド以外の)何らかのオブジェクトに再利用されているとロックするだろう。
また、実験してみたところ、ExitProcessでスレッドが終了すると_beginthreadの後始末処理が呼び出されず、ハンドルが閉じない。なので、ワーカースレッドが起動しっぱなしなのであれば、顧客は常にラッキーということになる。