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

Side by Side 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, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_WINDOWS) 6 #if defined(TARGET_OS_WINDOWS)
7 7
8 #include "bin/builtin.h" 8 #include "bin/builtin.h"
9 #include "bin/eventhandler.h" 9 #include "bin/eventhandler.h"
10 #include "bin/file.h" 10 #include "bin/file.h"
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 return NULL; 121 return NULL;
122 } 122 }
123 *port = SocketAddress::GetAddrPort(&raw); 123 *port = SocketAddress::GetAddrPort(&raw);
124 // Clear the port before calling WSAAddressToString as WSAAddressToString 124 // Clear the port before calling WSAAddressToString as WSAAddressToString
125 // includes the port in the formatted string. 125 // includes the port in the formatted string.
126 SocketAddress::SetAddrPort(&raw, 0); 126 SocketAddress::SetAddrPort(&raw, 0);
127 return new SocketAddress(&raw.addr); 127 return new SocketAddress(&raw.addr);
128 } 128 }
129 129
130 130
131 intptr_t Socket::Create(RawAddr addr) { 131 intptr_t Socket::Create(RawAddr addr) {
Søren Gjesse 2014/05/01 07:19:26 Rename this to CreateBind to match the naming.
Anders Johnsen 2014/05/01 08:05:11 That would force a rename on all platforms, which
Søren Gjesse 2014/05/01 09:42:38 Sure. We might want to add separate bind on all pl
Anders Johnsen 2014/05/01 10:48:31 Moving to Connect.
132 SOCKET s = socket(addr.ss.ss_family, SOCK_STREAM, 0); 132 SOCKET s = socket(addr.ss.ss_family, SOCK_STREAM, 0);
133 if (s == INVALID_SOCKET) { 133 if (s == INVALID_SOCKET) {
134 return -1; 134 return -1;
135 } 135 }
136 136
137 linger l; 137 linger l;
138 l.l_onoff = 1; 138 l.l_onoff = 1;
139 l.l_linger = 10; 139 l.l_linger = 10;
140 int status = setsockopt(s, 140 int status = setsockopt(s,
141 SOL_SOCKET, 141 SOL_SOCKET,
142 SO_LINGER, 142 SO_LINGER,
143 reinterpret_cast<char*>(&l), 143 reinterpret_cast<char*>(&l),
144 sizeof(l)); 144 sizeof(l));
145 if (status != NO_ERROR) { 145 if (status != NO_ERROR) {
146 FATAL("Failed setting SO_LINGER on socket"); 146 FATAL("Failed setting SO_LINGER on socket");
147 } 147 }
148 148
149 if (addr.ss.ss_family == AF_INET) {
150 struct sockaddr_in a;
151 memset(&a, 0, sizeof(a));
152 a.sin_family = AF_INET;
153 a.sin_addr.s_addr = INADDR_ANY;
154 a.sin_port = 0;
155 status = bind(s, reinterpret_cast<SOCKADDR*>(&a), sizeof(a));
156 } else {
157 struct sockaddr_in6 a;
158 memset(&a, 0, sizeof(a));
159 a.sin6_family = AF_INET6;
160 a.sin6_addr = in6addr_any;
161 a.sin6_port = 0;
162 status = bind(s, reinterpret_cast<SOCKADDR*>(&a), sizeof(a));
163 }
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.
164 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.
165 FATAL("Failed binding socket");
166 }
167
149 ClientSocket* client_socket = new ClientSocket(s); 168 ClientSocket* client_socket = new ClientSocket(s);
150 return reinterpret_cast<intptr_t>(client_socket); 169 return reinterpret_cast<intptr_t>(client_socket);
151 } 170 }
152 171
153 172
154 intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) { 173 intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) {
155 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); 174 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket());
156 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); 175 ClientSocket* handle = reinterpret_cast<ClientSocket*>(fd);
157 SOCKET s = handle->socket(); 176 SOCKET s = handle->socket();
158 SocketAddress::SetAddrPort(&addr, port); 177 SocketAddress::SetAddrPort(&addr, port);
159 int status = connect(s, &addr.addr, SocketAddress::GetAddrLength(&addr)); 178
160 if (status == SOCKET_ERROR) { 179 LPFN_CONNECTEX connectEx = NULL;
161 DWORD rc = WSAGetLastError(); 180 GUID guid_connect_ex = WSAID_CONNECTEX;
162 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd); 181 DWORD bytes;
163 client_socket->Close(); 182 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.
164 SetLastError(rc); 183 SIO_GET_EXTENSION_FUNCTION_POINTER,
165 return -1; 184 &guid_connect_ex,
185 sizeof(guid_connect_ex),
186 &connectEx,
187 sizeof(connectEx),
188 &bytes,
189 NULL,
190 NULL);
191 DWORD rc;
192 if (status != SOCKET_ERROR) {
193 handle->EnsureInitialized(EventHandler::delegate());
194
195 OverlappedBuffer* overlapped = OverlappedBuffer::AllocateConnectBuffer();
196
197 status = connectEx(s,
198 &addr.addr,
199 SocketAddress::GetAddrLength(&addr),
200 NULL,
201 0,
202 NULL,
203 overlapped->GetCleanOverlapped());
204
205
206 if (status == TRUE) {
207 handle->ConnectComplete(overlapped);
208 return fd;
209 } else if (WSAGetLastError() == ERROR_IO_PENDING) {
210 return fd;
211 }
212 rc = WSAGetLastError();
213 // Cleanup in case of error.
214 OverlappedBuffer::DisposeBuffer(overlapped);
215 } else {
216 rc = WSAGetLastError();
166 } 217 }
167 return fd; 218 handle->Close();
219 delete handle;
220 SetLastError(rc);
221 return -1;
168 } 222 }
169 223
170 224
171 intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) { 225 intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) {
172 intptr_t fd = Socket::Create(addr); 226 intptr_t fd = Socket::Create(addr);
173 if (fd < 0) { 227 if (fd < 0) {
174 return fd; 228 return fd;
175 } 229 }
176 230
177 return Socket::Connect(fd, addr, port); 231 return Socket::Connect(fd, addr, port);
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 proto, 701 proto,
648 MCAST_LEAVE_GROUP, 702 MCAST_LEAVE_GROUP,
649 reinterpret_cast<char *>(&mreq), 703 reinterpret_cast<char *>(&mreq),
650 sizeof(mreq)) == 0; 704 sizeof(mreq)) == 0;
651 } 705 }
652 706
653 } // namespace bin 707 } // namespace bin
654 } // namespace dart 708 } // namespace dart
655 709
656 #endif // defined(TARGET_OS_WINDOWS) 710 #endif // defined(TARGET_OS_WINDOWS)
OLDNEW
« 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