При использовании IOCP должен ли я установить для параметра hEvent WSAOVERLAPPED значение NULL или действительный дескриптор объекта WSAEVENT?

Согласно MSDN :

hEvent: если операция ввода-вывода с перекрытием выполняется без процедуры завершения ввода-вывода (параметр операции lpCompletionRoutine имеет значение null), то этот параметр должен содержать действительный дескриптор объекта WSAEVENT или быть нулевым.

Поскольку я использую IOCP, когда я вызываю WSASend () или WSARecv (), я передаю NULL их последнему параметру (т.е. lpCompletionRoutine):

WSASend(pIoRequest->GetSocket(), pIoRequest->GetWsaBuffer(), 1, NULL, pIoRequest->GetFlags(), pIoRequest, NULL);

WSARecv(pIoRequest->GetSocket(), pIoRequest->GetWsaBuffer(), 1, NULL, &(pIoRequest->GetFlags()), pIoRequest, NULL);

Мой класс "для данных ввода-вывода" (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?


person jpen    schedule 06.08.2012    source источник


Ответы (1)


person Ambroz Bizjak    schedule 06.08.2012
comment
Амброз: Спасибо за разъяснения. Могу я задать еще один вопрос? Имеет ли смысл иметь DWORD m_dwFlags в IoRequest (см. Отредактированный код выше)? Могу ли я вместо этого создать DWRD dwFlags на основе стека в моем рабочем потоке и передать его в WSASend () и WSARecv ()? - person jpen; 06.08.2012
comment
Кажется, что вы можете поместить его в стек и позволить ему выйти из области видимости, пока операция выполняется. Со страницы WSARecv: в этом случае lpNumberOfBytesRecvd и lpFlags не обновляются. WSASend не имеет этой проблемы, поскольку он просто принимает значение, а не указатель. - person Ambroz Bizjak; 06.08.2012