diff options
Diffstat (limited to 'net/base')
-rw-r--r-- | net/base/winsock_util.cc | 96 | ||||
-rw-r--r-- | net/base/winsock_util.h | 31 |
2 files changed, 127 insertions, 0 deletions
diff --git a/net/base/winsock_util.cc b/net/base/winsock_util.cc new file mode 100644 index 0000000..a3548d4 --- /dev/null +++ b/net/base/winsock_util.cc @@ -0,0 +1,96 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/base/winsock_util.h" + +#include "base/logging.h" +#include "net/base/net_errors.h" + +namespace net { + +namespace { + +// Prevent the compiler from optimizing away the arguments so they appear +// nicely on the stack in crash dumps. +#pragma warning (disable: 4748) +#pragma optimize( "", off ) + +// Pass the important values as function arguments so that they are available +// in crash dumps. +void CheckEventWait(WSAEVENT hEvent, DWORD wait_rv, DWORD expected) { + if (wait_rv != expected) { + DWORD err = ERROR_SUCCESS; + if (wait_rv == WAIT_FAILED) + err = GetLastError(); + CHECK(false); // Crash. + } +} + +#pragma optimize( "", on ) +#pragma warning (default: 4748) + +} // namespace + +void AssertEventNotSignaled(WSAEVENT hEvent) { + DWORD wait_rv = WaitForSingleObject(hEvent, 0); + CheckEventWait(hEvent, wait_rv, WAIT_TIMEOUT); +} + +bool ResetEventIfSignaled(WSAEVENT hEvent) { + // TODO(wtc): Remove the CHECKs after enough testing. + DWORD wait_rv = WaitForSingleObject(hEvent, 0); + if (wait_rv == WAIT_TIMEOUT) + return false; // The event object is not signaled. + CheckEventWait(hEvent, wait_rv, WAIT_OBJECT_0); + BOOL ok = WSAResetEvent(hEvent); + CHECK(ok); + return true; +} + +// Map winsock error to Chromium error. +int MapWinsockError(int os_error) { + // There are numerous Winsock error codes, but these are the ones we thus far + // find interesting. + switch (os_error) { + case WSAEACCES: + return ERR_ACCESS_DENIED; + case WSAENETDOWN: + return ERR_INTERNET_DISCONNECTED; + case WSAETIMEDOUT: + return ERR_TIMED_OUT; + case WSAECONNRESET: + case WSAENETRESET: // Related to keep-alive + return ERR_CONNECTION_RESET; + case WSAECONNABORTED: + return ERR_CONNECTION_ABORTED; + case WSAECONNREFUSED: + return ERR_CONNECTION_REFUSED; + case WSA_IO_INCOMPLETE: + case WSAEDISCON: + // WSAEDISCON is returned by WSARecv or WSARecvFrom for message-oriented + // sockets (where a return value of zero means a zero-byte message) to + // indicate graceful connection shutdown. We should not ever see this + // error code for TCP sockets, which are byte stream oriented. + LOG(DFATAL) << "Unexpected error " << os_error + << " mapped to net::ERR_UNEXPECTED"; + return ERR_UNEXPECTED; + case WSAEHOSTUNREACH: + case WSAENETUNREACH: + return ERR_ADDRESS_UNREACHABLE; + case WSAEADDRNOTAVAIL: + return ERR_ADDRESS_INVALID; + case WSAENOTCONN: + return ERR_SOCKET_NOT_CONNECTED; + case WSAEAFNOSUPPORT: + return ERR_ADDRESS_UNREACHABLE; + case ERROR_SUCCESS: + return OK; + default: + LOG(WARNING) << "Unknown error " << os_error + << " mapped to net::ERR_FAILED"; + return ERR_FAILED; + } +} + +} // namespace net diff --git a/net/base/winsock_util.h b/net/base/winsock_util.h new file mode 100644 index 0000000..c26e63f --- /dev/null +++ b/net/base/winsock_util.h @@ -0,0 +1,31 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_BASE_WINSOCK_UTIL_H_ +#define NET_BASE_WINSOCK_UTIL_H_ +#pragma once + +#include <winsock2.h> + +namespace net { + +// Assert that the (manual-reset) event object is not signaled. +void AssertEventNotSignaled(WSAEVENT hEvent); + +// If the (manual-reset) event object is signaled, resets it and returns true. +// Otherwise, does nothing and returns false. Called after a Winsock function +// succeeds synchronously +// +// Our testing shows that except in rare cases (when running inside QEMU), +// the event object is already signaled at this point, so we call this method +// to avoid a context switch in common cases. This is just a performance +// optimization. The code still works if this function simply returns false. +bool ResetEventIfSignaled(WSAEVENT hEvent); + +// Map winsock error to Chromium error. +int MapWinsockError(int os_error); + +} // namespace net + +#endif // NET_BASE_WINSOCK_UTIL_H_ |