OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 // winsock2.h must be included first in order to ensure it is included before | 8 // winsock2.h must be included first in order to ensure it is included before |
9 // windows.h. | 9 // windows.h. |
10 #include <winsock2.h> | 10 #include <winsock2.h> |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "base/eintr_wrapper.h" | 24 #include "base/eintr_wrapper.h" |
25 #include "net/base/net_util.h" | 25 #include "net/base/net_util.h" |
26 #include "net/base/listen_socket.h" | 26 #include "net/base/listen_socket.h" |
27 | 27 |
28 #if defined(OS_WIN) | 28 #if defined(OS_WIN) |
29 typedef int socklen_t; | 29 typedef int socklen_t; |
30 #endif // defined(OS_WIN) | 30 #endif // defined(OS_WIN) |
31 | 31 |
32 namespace { | 32 namespace { |
33 | 33 |
34 const int kReadBufSize = 200; | 34 const int kReadBufSize = 4096; |
35 | 35 |
36 } // namespace | 36 } // namespace |
37 | 37 |
38 #if defined(OS_WIN) | 38 #if defined(OS_WIN) |
39 const SOCKET ListenSocket::kInvalidSocket = INVALID_SOCKET; | 39 const SOCKET ListenSocket::kInvalidSocket = INVALID_SOCKET; |
40 const int ListenSocket::kSocketError = SOCKET_ERROR; | 40 const int ListenSocket::kSocketError = SOCKET_ERROR; |
41 #elif defined(OS_POSIX) | 41 #elif defined(OS_POSIX) |
42 const SOCKET ListenSocket::kInvalidSocket = -1; | 42 const SOCKET ListenSocket::kInvalidSocket = -1; |
43 const int ListenSocket::kSocketError = -1; | 43 const int ListenSocket::kSocketError = -1; |
44 #endif | 44 #endif |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } else if (len == 0) { | 153 } else if (len == 0) { |
154 // In Windows, Close() is called by OnObjectSignaled. In POSIX, we need | 154 // In Windows, Close() is called by OnObjectSignaled. In POSIX, we need |
155 // to call it here. | 155 // to call it here. |
156 #if defined(OS_POSIX) | 156 #if defined(OS_POSIX) |
157 Close(); | 157 Close(); |
158 #endif | 158 #endif |
159 } else { | 159 } else { |
160 // TODO(ibrar): maybe change DidRead to take a length instead | 160 // TODO(ibrar): maybe change DidRead to take a length instead |
161 DCHECK(len > 0 && len <= kReadBufSize); | 161 DCHECK(len > 0 && len <= kReadBufSize); |
162 buf[len] = 0; // already create a buffer with +1 length | 162 buf[len] = 0; // already create a buffer with +1 length |
163 socket_delegate_->DidRead(this, buf); | 163 socket_delegate_->DidRead(this, buf, len); |
164 } | 164 } |
165 } while (len == kReadBufSize); | 165 } while (len == kReadBufSize); |
166 } | 166 } |
167 | 167 |
168 void ListenSocket::CloseSocket(SOCKET s) { | 168 void ListenSocket::CloseSocket(SOCKET s) { |
169 if (s && s != kInvalidSocket) { | 169 if (s && s != kInvalidSocket) { |
170 UnwatchSocket(); | 170 UnwatchSocket(); |
171 #if defined(OS_WIN) | 171 #if defined(OS_WIN) |
172 closesocket(s); | 172 closesocket(s); |
173 #elif defined(OS_POSIX) | 173 #elif defined(OS_POSIX) |
(...skipping 25 matching lines...) Expand all Loading... |
199 watcher_.StartWatching(socket_event_, this); | 199 watcher_.StartWatching(socket_event_, this); |
200 #elif defined(OS_POSIX) | 200 #elif defined(OS_POSIX) |
201 // Implicitly calls StartWatchingFileDescriptor(). | 201 // Implicitly calls StartWatchingFileDescriptor(). |
202 MessageLoopForIO::current()->WatchFileDescriptor( | 202 MessageLoopForIO::current()->WatchFileDescriptor( |
203 socket_, true, MessageLoopForIO::WATCH_READ, &watcher_, this); | 203 socket_, true, MessageLoopForIO::WATCH_READ, &watcher_, this); |
204 wait_state_ = state; | 204 wait_state_ = state; |
205 #endif | 205 #endif |
206 } | 206 } |
207 | 207 |
208 void ListenSocket::SendInternal(const char* bytes, int len) { | 208 void ListenSocket::SendInternal(const char* bytes, int len) { |
209 int sent = HANDLE_EINTR(send(socket_, bytes, len, 0)); | 209 char* send_buf = const_cast<char *>(bytes); |
210 if (sent == kSocketError) { | 210 int len_left = len; |
| 211 while (true) { |
| 212 int sent = HANDLE_EINTR(send(socket_, send_buf, len_left, 0)); |
| 213 if (sent == len_left) { // A shortcut to avoid extraneous checks. |
| 214 break; |
| 215 } |
| 216 if (sent == kSocketError) { |
211 #if defined(OS_WIN) | 217 #if defined(OS_WIN) |
212 int err = WSAGetLastError(); | 218 if (WSAGetLastError() != WSAEWOULDBLOCK) { |
213 if (err == WSAEWOULDBLOCK) { | 219 LOG(ERROR) << "send failed: WSAGetLastError()==" << WSAGetLastError(); |
214 #elif defined(OS_POSIX) | 220 #elif defined(OS_POSIX) |
215 if (errno == EWOULDBLOCK || errno == EAGAIN) { | 221 if (errno != EWOULDBLOCK && errno != EAGAIN) { |
| 222 LOG(ERROR) << "send failed: errno==" << errno; |
216 #endif | 223 #endif |
217 // TODO(ibrar): there should be logic here to handle this because | 224 break; |
218 // it is not an error | 225 } |
| 226 // Otherwise we would block, and now we have to wait for a retry. |
| 227 // Fall through to PlatformThread::YieldCurrentThread() |
| 228 } else { |
| 229 // sent != len_left according to the shortcut above. |
| 230 // Shift the buffer start and send the remainder after a short while. |
| 231 send_buf += sent; |
| 232 len_left -= sent; |
219 } | 233 } |
220 } else if (sent != len) { | 234 PlatformThread::YieldCurrentThread(); |
221 LOG(ERROR) << "send failed: "; | |
222 } | 235 } |
223 } | 236 } |
224 | 237 |
225 void ListenSocket::Send(const char* bytes, int len, bool append_linefeed) { | 238 void ListenSocket::Send(const char* bytes, int len, bool append_linefeed) { |
226 SendInternal(bytes, len); | 239 SendInternal(bytes, len); |
227 if (append_linefeed) { | 240 if (append_linefeed) { |
228 SendInternal("\r\n", 2); | 241 SendInternal("\r\n", 2); |
229 } | 242 } |
230 } | 243 } |
231 | 244 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 } | 310 } |
298 } | 311 } |
299 | 312 |
300 void ListenSocket::OnFileCanWriteWithoutBlocking(int fd) { | 313 void ListenSocket::OnFileCanWriteWithoutBlocking(int fd) { |
301 // MessagePumpLibevent callback, we don't listen for write events | 314 // MessagePumpLibevent callback, we don't listen for write events |
302 // so we shouldn't ever reach here. | 315 // so we shouldn't ever reach here. |
303 NOTREACHED(); | 316 NOTREACHED(); |
304 } | 317 } |
305 | 318 |
306 #endif | 319 #endif |
OLD | NEW |