非同期sendの処理の流れメモ

以前に勉強したのですが、WinSockのブロック処理のうちacceptやrecvの非同期化は割と直感的に実装が可能です。
今回ちょっと頭を悩ましたというか、どういう風に使えばいいのか分からなかったのが、sendの非同期処理化です。
FD_WRITEイベントが発生するのはどういうときなのか?ということなのですが、これは「send可能になった」という瞬間に発生するイベントです。では、send不可能、というのはどういうときか。それがWSAEWOULDBLOCKというエラーが発生しているときなのです。
つまり、擬似コードで書くと以下のようになります。

// 非同期初期化.
WSAAsyncSelect( socket, .. , FD_WRITE );
// フラグ定義.
bool isSendable = false;
// send処理の部分.
if( isSendable ){
  int ret = send( .. ); // send処理.
  if( ret == SOCKET_ERROR ){
    if( WSAGetLastError() == WSAEWOULDBLOCK ){
      isSendable = false;
    }
  }
}
// ウィンドウイベント受け取り部分
switch( WSAGETSELECTEVENT(lParam) ){
case FD_WRITE:
  isSendable = true;
  break;
}

こんな感じなので、sendで送りたいメッセージはキューに溜めるように実装しないと非同期sendの実現は難しいですね。