Beispiel #1
0
int
main ()
{
  if (check_read_write () != 0)
    return 1;
  return 0;
}
Beispiel #2
0
bool waithandle::wait_handles(const list& handles, const std::chrono::milliseconds* ms)
{
    assert(std::distance(std::begin(handles), std::end(handles)) > 0);

    std::vector<HANDLE> vec;
    for (auto& handle : handles)
    {
        vec.push_back(handle->handle_);
    }

    const DWORD start  = GetTickCount();
    const DWORD span   = ms ? (DWORD)ms->count() : 0;
    const DWORD nCount = static_cast<DWORD>(vec.size());
    
    DWORD now = start;
    DWORD signaled = -1;
    
    while (true)
    {      
        if ((now - start) > span)
            break;
            
        const DWORD timeout = ms ? (span - (now - start)) : INFINITE;
      
        const DWORD ret = WaitForMultipleObjectsEx(nCount, &vec[0], FALSE, timeout, FALSE);
        if (ret == WAIT_FAILED)
            throw std::runtime_error("wait failed");
        else if (ret == WAIT_TIMEOUT)
            break;

        signaled = ret - WAIT_OBJECT_0;

        auto handle = handles[ret - WAIT_OBJECT_0];
        if (handle->type_ == waithandle::type::socket)
        {
            // unfortunately WaitForMultipleObjects doesn't tell us what
            // is available when the wait handle is associated with a socket.
            // thus we have to make another call to check if the handle is signaled
            // for writeability or readability.
            // also if neither is set then we assume that the socket is in connecting state
            // and the result is now available  (FD_CONNECT in WSAEventSelect).
            // We translate this to "readability" to follow linux semantics.
            const std::pair<bool, bool>& state = check_read_write(handle->extra.socket_);

            if ((state.first && handle->read_) || (state.second && handle->write_))
            {
                handle->read_  = state.first;
                handle->write_ = state.second;
                break;
            }
            else if (!state.first && !state.second)
            {
                // assume connect() completed.
                handle->read_  = true;
                handle->write_ = false;
                break;
            }
        }
        else
        {
            handle->read_  = true;
            handle->write_ = false;
            break;
        }
        now = GetTickCount();
        // todo: deal with wrapround, i.e. if now < start
    }

    for (DWORD i=0; i<nCount; ++i)
    {
        if (i == signaled)
            continue;
        handles[i]->read_  = false;
        handles[i]->write_ = false;
    }
    if (signaled == -1)
        return false;

    return true;

}