Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(103)

Unified Diff: runtime/bin/socket_win.cc

Issue 264613002: Use ConnectEx on Windows, to do async connect of sockets. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« runtime/bin/eventhandler_win.cc ('K') | « runtime/bin/eventhandler_win.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/socket_win.cc
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index 7f1de2d94c4b97994551d90f09514306bad348db..b58b81d8140f0406681e18faf01d5d8b062c2b65 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -146,6 +146,25 @@ intptr_t Socket::Create(RawAddr addr) {
FATAL("Failed setting SO_LINGER on socket");
}
+ if (addr.ss.ss_family == AF_INET) {
+ struct sockaddr_in a;
+ memset(&a, 0, sizeof(a));
+ a.sin_family = AF_INET;
+ a.sin_addr.s_addr = INADDR_ANY;
+ a.sin_port = 0;
+ status = bind(s, reinterpret_cast<SOCKADDR*>(&a), sizeof(a));
+ } else {
+ struct sockaddr_in6 a;
+ memset(&a, 0, sizeof(a));
+ a.sin6_family = AF_INET6;
+ a.sin6_addr = in6addr_any;
+ a.sin6_port = 0;
+ status = bind(s, reinterpret_cast<SOCKADDR*>(&a), sizeof(a));
+ }
Søren Gjesse 2014/05/01 07:19:26 Can't you use the same code as is used for the oth
Anders Johnsen 2014/05/01 08:05:11 Done.
+ if (status != NO_ERROR) {
Søren Gjesse 2014/05/01 07:19:26 This should not be fatal.
Anders Johnsen 2014/05/01 08:05:11 Done.
+ FATAL("Failed binding socket");
+ }
+
ClientSocket* client_socket = new ClientSocket(s);
return reinterpret_cast<intptr_t>(client_socket);
}
@@ -153,18 +172,53 @@ intptr_t Socket::Create(RawAddr addr) {
intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) {
ASSERT(reinterpret_cast<Handle*>(fd)->is_socket());
- SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
+ ClientSocket* handle = reinterpret_cast<ClientSocket*>(fd);
SOCKET s = handle->socket();
SocketAddress::SetAddrPort(&addr, port);
- int status = connect(s, &addr.addr, SocketAddress::GetAddrLength(&addr));
- if (status == SOCKET_ERROR) {
- DWORD rc = WSAGetLastError();
- ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd);
- client_socket->Close();
- SetLastError(rc);
- return -1;
+
+ LPFN_CONNECTEX connectEx = NULL;
+ GUID guid_connect_ex = WSAID_CONNECTEX;
+ DWORD bytes;
+ int status = WSAIoctl(s,
Søren Gjesse 2014/05/01 07:19:26 Are you sure you cannot just load this once like i
Anders Johnsen 2014/05/01 08:05:11 No, it's using the socket as an argument. Also, it
Søren Gjesse 2014/05/01 09:42:38 Of cause you are right.
+ SIO_GET_EXTENSION_FUNCTION_POINTER,
+ &guid_connect_ex,
+ sizeof(guid_connect_ex),
+ &connectEx,
+ sizeof(connectEx),
+ &bytes,
+ NULL,
+ NULL);
+ DWORD rc;
+ if (status != SOCKET_ERROR) {
+ handle->EnsureInitialized(EventHandler::delegate());
+
+ OverlappedBuffer* overlapped = OverlappedBuffer::AllocateConnectBuffer();
+
+ status = connectEx(s,
+ &addr.addr,
+ SocketAddress::GetAddrLength(&addr),
+ NULL,
+ 0,
+ NULL,
+ overlapped->GetCleanOverlapped());
+
+
+ if (status == TRUE) {
+ handle->ConnectComplete(overlapped);
+ return fd;
+ } else if (WSAGetLastError() == ERROR_IO_PENDING) {
+ return fd;
+ }
+ rc = WSAGetLastError();
+ // Cleanup in case of error.
+ OverlappedBuffer::DisposeBuffer(overlapped);
+ } else {
+ rc = WSAGetLastError();
}
- return fd;
+ handle->Close();
+ delete handle;
+ SetLastError(rc);
+ return -1;
}
« runtime/bin/eventhandler_win.cc ('K') | « runtime/bin/eventhandler_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698