| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 26 matching lines...) Expand all Loading... |
| 37 } // namespace | 37 } // namespace |
| 38 | 38 |
| 39 #if defined(OS_WIN) | 39 #if defined(OS_WIN) |
| 40 const SOCKET ListenSocket::kInvalidSocket = INVALID_SOCKET; | 40 const SOCKET ListenSocket::kInvalidSocket = INVALID_SOCKET; |
| 41 const int ListenSocket::kSocketError = SOCKET_ERROR; | 41 const int ListenSocket::kSocketError = SOCKET_ERROR; |
| 42 #elif defined(OS_POSIX) | 42 #elif defined(OS_POSIX) |
| 43 const SOCKET ListenSocket::kInvalidSocket = -1; | 43 const SOCKET ListenSocket::kInvalidSocket = -1; |
| 44 const int ListenSocket::kSocketError = -1; | 44 const int ListenSocket::kSocketError = -1; |
| 45 #endif | 45 #endif |
| 46 | 46 |
| 47 ListenSocket* ListenSocket::Listen(std::string ip, int port, |
| 48 ListenSocketDelegate* del) { |
| 49 SOCKET s = Listen(ip, port); |
| 50 if (s == kInvalidSocket) { |
| 51 // TODO(erikkay): error handling |
| 52 } else { |
| 53 ListenSocket* sock = new ListenSocket(s, del); |
| 54 sock->Listen(); |
| 55 return sock; |
| 56 } |
| 57 return NULL; |
| 58 } |
| 59 |
| 60 void ListenSocket::Send(const char* bytes, int len, bool append_linefeed) { |
| 61 SendInternal(bytes, len); |
| 62 if (append_linefeed) { |
| 63 SendInternal("\r\n", 2); |
| 64 } |
| 65 } |
| 66 |
| 67 void ListenSocket::Send(const std::string& str, bool append_linefeed) { |
| 68 Send(str.data(), static_cast<int>(str.length()), append_linefeed); |
| 69 } |
| 70 |
| 71 void ListenSocket::PauseReads() { |
| 72 DCHECK(!reads_paused_); |
| 73 reads_paused_ = true; |
| 74 } |
| 75 |
| 76 void ListenSocket::ResumeReads() { |
| 77 DCHECK(reads_paused_); |
| 78 reads_paused_ = false; |
| 79 if (has_pending_reads_) { |
| 80 has_pending_reads_ = false; |
| 81 Read(); |
| 82 } |
| 83 } |
| 84 |
| 47 ListenSocket::ListenSocket(SOCKET s, ListenSocketDelegate *del) | 85 ListenSocket::ListenSocket(SOCKET s, ListenSocketDelegate *del) |
| 48 : socket_(s), | 86 : socket_(s), |
| 49 socket_delegate_(del), | 87 socket_delegate_(del), |
| 50 reads_paused_(false), | 88 reads_paused_(false), |
| 51 has_pending_reads_(false) { | 89 has_pending_reads_(false) { |
| 52 #if defined(OS_WIN) | 90 #if defined(OS_WIN) |
| 53 socket_event_ = WSACreateEvent(); | 91 socket_event_ = WSACreateEvent(); |
| 54 // TODO(ibrar): error handling in case of socket_event_ == WSA_INVALID_EVENT | 92 // TODO(ibrar): error handling in case of socket_event_ == WSA_INVALID_EVENT |
| 55 WatchSocket(NOT_WAITING); | 93 WatchSocket(NOT_WAITING); |
| 56 #endif | 94 #endif |
| (...skipping 22 matching lines...) Expand all Loading... |
| 79 closesocket(s); | 117 closesocket(s); |
| 80 #elif defined(OS_POSIX) | 118 #elif defined(OS_POSIX) |
| 81 close(s); | 119 close(s); |
| 82 #endif | 120 #endif |
| 83 s = kInvalidSocket; | 121 s = kInvalidSocket; |
| 84 } | 122 } |
| 85 } | 123 } |
| 86 return s; | 124 return s; |
| 87 } | 125 } |
| 88 | 126 |
| 89 ListenSocket* ListenSocket::Listen(std::string ip, int port, | 127 SOCKET ListenSocket::Accept(SOCKET s) { |
| 90 ListenSocketDelegate* del) { | 128 sockaddr_in from; |
| 91 SOCKET s = Listen(ip, port); | 129 socklen_t from_len = sizeof(from); |
| 92 if (s == kInvalidSocket) { | 130 SOCKET conn = |
| 93 // TODO(erikkay): error handling | 131 HANDLE_EINTR(accept(s, reinterpret_cast<sockaddr*>(&from), &from_len)); |
| 94 } else { | 132 if (conn != kInvalidSocket) { |
| 95 ListenSocket* sock = new ListenSocket(s, del); | 133 net::SetNonBlocking(conn); |
| 96 sock->Listen(); | |
| 97 return sock; | |
| 98 } | 134 } |
| 99 return NULL; | 135 return conn; |
| 136 } |
| 137 |
| 138 void ListenSocket::SendInternal(const char* bytes, int len) { |
| 139 char* send_buf = const_cast<char *>(bytes); |
| 140 int len_left = len; |
| 141 while (true) { |
| 142 int sent = HANDLE_EINTR(send(socket_, send_buf, len_left, 0)); |
| 143 if (sent == len_left) { // A shortcut to avoid extraneous checks. |
| 144 break; |
| 145 } |
| 146 if (sent == kSocketError) { |
| 147 #if defined(OS_WIN) |
| 148 if (WSAGetLastError() != WSAEWOULDBLOCK) { |
| 149 LOG(ERROR) << "send failed: WSAGetLastError()==" << WSAGetLastError(); |
| 150 #elif defined(OS_POSIX) |
| 151 if (errno != EWOULDBLOCK && errno != EAGAIN) { |
| 152 LOG(ERROR) << "send failed: errno==" << errno; |
| 153 #endif |
| 154 break; |
| 155 } |
| 156 // Otherwise we would block, and now we have to wait for a retry. |
| 157 // Fall through to PlatformThread::YieldCurrentThread() |
| 158 } else { |
| 159 // sent != len_left according to the shortcut above. |
| 160 // Shift the buffer start and send the remainder after a short while. |
| 161 send_buf += sent; |
| 162 len_left -= sent; |
| 163 } |
| 164 base::PlatformThread::YieldCurrentThread(); |
| 165 } |
| 100 } | 166 } |
| 101 | 167 |
| 102 void ListenSocket::Listen() { | 168 void ListenSocket::Listen() { |
| 103 int backlog = 10; // TODO(erikkay): maybe don't allow any backlog? | 169 int backlog = 10; // TODO(erikkay): maybe don't allow any backlog? |
| 104 listen(socket_, backlog); | 170 listen(socket_, backlog); |
| 105 // TODO(erikkay): error handling | 171 // TODO(erikkay): error handling |
| 106 #if defined(OS_POSIX) | 172 #if defined(OS_POSIX) |
| 107 WatchSocket(WAITING_ACCEPT); | 173 WatchSocket(WAITING_ACCEPT); |
| 108 #endif | 174 #endif |
| 109 } | 175 } |
| 110 | 176 |
| 111 SOCKET ListenSocket::Accept(SOCKET s) { | |
| 112 sockaddr_in from; | |
| 113 socklen_t from_len = sizeof(from); | |
| 114 SOCKET conn = | |
| 115 HANDLE_EINTR(accept(s, reinterpret_cast<sockaddr*>(&from), &from_len)); | |
| 116 if (conn != kInvalidSocket) { | |
| 117 net::SetNonBlocking(conn); | |
| 118 } | |
| 119 return conn; | |
| 120 } | |
| 121 | |
| 122 void ListenSocket::Accept() { | 177 void ListenSocket::Accept() { |
| 123 SOCKET conn = Accept(socket_); | 178 SOCKET conn = Accept(socket_); |
| 124 if (conn != kInvalidSocket) { | 179 if (conn != kInvalidSocket) { |
| 125 scoped_refptr<ListenSocket> sock( | 180 scoped_refptr<ListenSocket> sock( |
| 126 new ListenSocket(conn, socket_delegate_)); | 181 new ListenSocket(conn, socket_delegate_)); |
| 127 // it's up to the delegate to AddRef if it wants to keep it around | 182 // it's up to the delegate to AddRef if it wants to keep it around |
| 128 #if defined(OS_POSIX) | 183 #if defined(OS_POSIX) |
| 129 sock->WatchSocket(WAITING_READ); | 184 sock->WatchSocket(WAITING_READ); |
| 130 #endif | 185 #endif |
| 131 socket_delegate_->DidAccept(this, sock); | 186 socket_delegate_->DidAccept(this, sock); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 159 #endif | 214 #endif |
| 160 } else { | 215 } else { |
| 161 // TODO(ibrar): maybe change DidRead to take a length instead | 216 // TODO(ibrar): maybe change DidRead to take a length instead |
| 162 DCHECK(len > 0 && len <= kReadBufSize); | 217 DCHECK(len > 0 && len <= kReadBufSize); |
| 163 buf[len] = 0; // already create a buffer with +1 length | 218 buf[len] = 0; // already create a buffer with +1 length |
| 164 socket_delegate_->DidRead(this, buf, len); | 219 socket_delegate_->DidRead(this, buf, len); |
| 165 } | 220 } |
| 166 } while (len == kReadBufSize); | 221 } while (len == kReadBufSize); |
| 167 } | 222 } |
| 168 | 223 |
| 169 void ListenSocket::CloseSocket(SOCKET s) { | |
| 170 if (s && s != kInvalidSocket) { | |
| 171 UnwatchSocket(); | |
| 172 #if defined(OS_WIN) | |
| 173 closesocket(s); | |
| 174 #elif defined(OS_POSIX) | |
| 175 close(s); | |
| 176 #endif | |
| 177 } | |
| 178 } | |
| 179 | |
| 180 void ListenSocket::Close() { | 224 void ListenSocket::Close() { |
| 181 #if defined(OS_POSIX) | 225 #if defined(OS_POSIX) |
| 182 if (wait_state_ == WAITING_CLOSE) | 226 if (wait_state_ == WAITING_CLOSE) |
| 183 return; | 227 return; |
| 184 wait_state_ = WAITING_CLOSE; | 228 wait_state_ = WAITING_CLOSE; |
| 185 #endif | 229 #endif |
| 186 socket_delegate_->DidClose(this); | 230 socket_delegate_->DidClose(this); |
| 187 } | 231 } |
| 188 | 232 |
| 189 void ListenSocket::UnwatchSocket() { | 233 void ListenSocket::CloseSocket(SOCKET s) { |
| 234 if (s && s != kInvalidSocket) { |
| 235 UnwatchSocket(); |
| 190 #if defined(OS_WIN) | 236 #if defined(OS_WIN) |
| 191 watcher_.StopWatching(); | 237 closesocket(s); |
| 192 #elif defined(OS_POSIX) | 238 #elif defined(OS_POSIX) |
| 193 watcher_.StopWatchingFileDescriptor(); | 239 close(s); |
| 194 #endif | 240 #endif |
| 241 } |
| 195 } | 242 } |
| 196 | 243 |
| 197 void ListenSocket::WatchSocket(WaitState state) { | 244 void ListenSocket::WatchSocket(WaitState state) { |
| 198 #if defined(OS_WIN) | 245 #if defined(OS_WIN) |
| 199 WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ); | 246 WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ); |
| 200 watcher_.StartWatching(socket_event_, this); | 247 watcher_.StartWatching(socket_event_, this); |
| 201 #elif defined(OS_POSIX) | 248 #elif defined(OS_POSIX) |
| 202 // Implicitly calls StartWatchingFileDescriptor(). | 249 // Implicitly calls StartWatchingFileDescriptor(). |
| 203 MessageLoopForIO::current()->WatchFileDescriptor( | 250 MessageLoopForIO::current()->WatchFileDescriptor( |
| 204 socket_, true, MessageLoopForIO::WATCH_READ, &watcher_, this); | 251 socket_, true, MessageLoopForIO::WATCH_READ, &watcher_, this); |
| 205 wait_state_ = state; | 252 wait_state_ = state; |
| 206 #endif | 253 #endif |
| 207 } | 254 } |
| 208 | 255 |
| 209 void ListenSocket::SendInternal(const char* bytes, int len) { | 256 void ListenSocket::UnwatchSocket() { |
| 210 char* send_buf = const_cast<char *>(bytes); | |
| 211 int len_left = len; | |
| 212 while (true) { | |
| 213 int sent = HANDLE_EINTR(send(socket_, send_buf, len_left, 0)); | |
| 214 if (sent == len_left) { // A shortcut to avoid extraneous checks. | |
| 215 break; | |
| 216 } | |
| 217 if (sent == kSocketError) { | |
| 218 #if defined(OS_WIN) | 257 #if defined(OS_WIN) |
| 219 if (WSAGetLastError() != WSAEWOULDBLOCK) { | 258 watcher_.StopWatching(); |
| 220 LOG(ERROR) << "send failed: WSAGetLastError()==" << WSAGetLastError(); | |
| 221 #elif defined(OS_POSIX) | 259 #elif defined(OS_POSIX) |
| 222 if (errno != EWOULDBLOCK && errno != EAGAIN) { | 260 watcher_.StopWatchingFileDescriptor(); |
| 223 LOG(ERROR) << "send failed: errno==" << errno; | |
| 224 #endif | 261 #endif |
| 225 break; | |
| 226 } | |
| 227 // Otherwise we would block, and now we have to wait for a retry. | |
| 228 // Fall through to PlatformThread::YieldCurrentThread() | |
| 229 } else { | |
| 230 // sent != len_left according to the shortcut above. | |
| 231 // Shift the buffer start and send the remainder after a short while. | |
| 232 send_buf += sent; | |
| 233 len_left -= sent; | |
| 234 } | |
| 235 base::PlatformThread::YieldCurrentThread(); | |
| 236 } | |
| 237 } | |
| 238 | |
| 239 void ListenSocket::Send(const char* bytes, int len, bool append_linefeed) { | |
| 240 SendInternal(bytes, len); | |
| 241 if (append_linefeed) { | |
| 242 SendInternal("\r\n", 2); | |
| 243 } | |
| 244 } | |
| 245 | |
| 246 void ListenSocket::Send(const std::string& str, bool append_linefeed) { | |
| 247 Send(str.data(), static_cast<int>(str.length()), append_linefeed); | |
| 248 } | |
| 249 | |
| 250 void ListenSocket::PauseReads() { | |
| 251 DCHECK(!reads_paused_); | |
| 252 reads_paused_ = true; | |
| 253 } | |
| 254 | |
| 255 void ListenSocket::ResumeReads() { | |
| 256 DCHECK(reads_paused_); | |
| 257 reads_paused_ = false; | |
| 258 if (has_pending_reads_) { | |
| 259 has_pending_reads_ = false; | |
| 260 Read(); | |
| 261 } | |
| 262 } | 262 } |
| 263 | 263 |
| 264 // TODO(ibrar): We can add these functions into OS dependent files | 264 // TODO(ibrar): We can add these functions into OS dependent files |
| 265 #if defined(OS_WIN) | 265 #if defined(OS_WIN) |
| 266 // MessageLoop watcher callback | 266 // MessageLoop watcher callback |
| 267 void ListenSocket::OnObjectSignaled(HANDLE object) { | 267 void ListenSocket::OnObjectSignaled(HANDLE object) { |
| 268 WSANETWORKEVENTS ev; | 268 WSANETWORKEVENTS ev; |
| 269 if (kSocketError == WSAEnumNetworkEvents(socket_, socket_event_, &ev)) { | 269 if (kSocketError == WSAEnumNetworkEvents(socket_, socket_event_, &ev)) { |
| 270 // TODO | 270 // TODO |
| 271 return; | 271 return; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 } | 311 } |
| 312 } | 312 } |
| 313 | 313 |
| 314 void ListenSocket::OnFileCanWriteWithoutBlocking(int fd) { | 314 void ListenSocket::OnFileCanWriteWithoutBlocking(int fd) { |
| 315 // MessagePumpLibevent callback, we don't listen for write events | 315 // MessagePumpLibevent callback, we don't listen for write events |
| 316 // so we shouldn't ever reach here. | 316 // so we shouldn't ever reach here. |
| 317 NOTREACHED(); | 317 NOTREACHED(); |
| 318 } | 318 } |
| 319 | 319 |
| 320 #endif | 320 #endif |
| OLD | NEW |