MSDNによると:
hEvent : オーバーラップされた I/O 操作が I/O 完了ルーチンなしで発行された場合 (操作の lpCompletionRoutine パラメーターが null に設定されている)、このパラメーターには WSAEVENT オブジェクトへの有効なハンドルが含まれているか、null である必要があります。
私は IOCP を使用しているので、WSASend() または WSARecv() を呼び出すときに、最後のパラメーター (つまり、lpCompletionRoutine) に NULL を渡します。
WSASend(pIoRequest->GetSocket(), pIoRequest->GetWsaBuffer(), 1, NULL, pIoRequest->GetFlags(), pIoRequest, NULL);
WSARecv(pIoRequest->GetSocket(), pIoRequest->GetWsaBuffer(), 1, NULL, &(pIoRequest->GetFlags()), pIoRequest, NULL);
「I/O データごと」のクラス (pIoRequest) は次のようになります。
class IoRequest : public WSAOVERLAPPED
{
public:
IoRequest()
{
...
SecureZeroMemory(this, sizeof(WSAOVERLAPPED));
hEvent = WSACreateEvent(); // A
}
...
void ResetForNextIoRequest()
{
WSACloseEvent(hEvent); // B
SecureZeroMemory(this, sizeof(WSAOVERLAPPED));
hEvent = WSACreateEvent(); // C
...
}
...
DWORD& GetFlags() { return m_dwFlags; }
...
private:
...
DWORD m_dwFlags;
...
};
上記の A、B、C の行をコメントアウトしても、プログラムの動作に違いはないようです。
では、いつ WSACreateEvent() を呼び出すか、単に hEvent を NULL に設定するかをどのように決定すればよいでしょうか?