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 "net/socket/tcp_client_socket_libevent.h" | 5 #include "net/socket/tcp_client_socket_libevent.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <netdb.h> | 9 #include <netdb.h> |
10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 write_callback_(NULL), | 137 write_callback_(NULL), |
138 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { | 138 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { |
139 } | 139 } |
140 | 140 |
141 TCPClientSocketLibevent::~TCPClientSocketLibevent() { | 141 TCPClientSocketLibevent::~TCPClientSocketLibevent() { |
142 Disconnect(); | 142 Disconnect(); |
143 net_log_.AddEvent(NetLog::TYPE_TCP_SOCKET_DONE, NULL); | 143 net_log_.AddEvent(NetLog::TYPE_TCP_SOCKET_DONE, NULL); |
144 } | 144 } |
145 | 145 |
146 int TCPClientSocketLibevent::Connect(CompletionCallback* callback) { | 146 int TCPClientSocketLibevent::Connect(CompletionCallback* callback) { |
| 147 DCHECK(CalledOnValidThread()); |
| 148 |
147 // If already connected, then just return OK. | 149 // If already connected, then just return OK. |
148 if (socket_ != kInvalidSocket) | 150 if (socket_ != kInvalidSocket) |
149 return OK; | 151 return OK; |
150 | 152 |
151 DCHECK(!waiting_connect_); | 153 DCHECK(!waiting_connect_); |
152 | 154 |
153 TRACE_EVENT_BEGIN("socket.connect", this, ""); | 155 TRACE_EVENT_BEGIN("socket.connect", this, ""); |
154 | 156 |
155 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT, NULL); | 157 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT, NULL); |
156 | 158 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 DLOG(INFO) << "WatchFileDescriptor failed: " << errno; | 213 DLOG(INFO) << "WatchFileDescriptor failed: " << errno; |
212 close(socket_); | 214 close(socket_); |
213 socket_ = kInvalidSocket; | 215 socket_ = kInvalidSocket; |
214 return MapPosixError(errno); | 216 return MapPosixError(errno); |
215 } | 217 } |
216 | 218 |
217 return ERR_IO_PENDING; | 219 return ERR_IO_PENDING; |
218 } | 220 } |
219 | 221 |
220 void TCPClientSocketLibevent::Disconnect() { | 222 void TCPClientSocketLibevent::Disconnect() { |
| 223 DCHECK(CalledOnValidThread()); |
| 224 |
221 if (socket_ == kInvalidSocket) | 225 if (socket_ == kInvalidSocket) |
222 return; | 226 return; |
223 | 227 |
224 TRACE_EVENT_INSTANT("socket.disconnect", this, ""); | 228 TRACE_EVENT_INSTANT("socket.disconnect", this, ""); |
225 | 229 |
226 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 230 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
227 DCHECK(ok); | 231 DCHECK(ok); |
228 ok = write_socket_watcher_.StopWatchingFileDescriptor(); | 232 ok = write_socket_watcher_.StopWatchingFileDescriptor(); |
229 DCHECK(ok); | 233 DCHECK(ok); |
230 close(socket_); | 234 close(socket_); |
231 socket_ = kInvalidSocket; | 235 socket_ = kInvalidSocket; |
232 waiting_connect_ = false; | 236 waiting_connect_ = false; |
233 | 237 |
234 // Reset for next time. | 238 // Reset for next time. |
235 current_ai_ = addresses_.head(); | 239 current_ai_ = addresses_.head(); |
236 } | 240 } |
237 | 241 |
238 bool TCPClientSocketLibevent::IsConnected() const { | 242 bool TCPClientSocketLibevent::IsConnected() const { |
| 243 DCHECK(CalledOnValidThread()); |
| 244 |
239 if (socket_ == kInvalidSocket || waiting_connect_) | 245 if (socket_ == kInvalidSocket || waiting_connect_) |
240 return false; | 246 return false; |
241 | 247 |
242 // Check if connection is alive. | 248 // Check if connection is alive. |
243 char c; | 249 char c; |
244 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK)); | 250 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK)); |
245 if (rv == 0) | 251 if (rv == 0) |
246 return false; | 252 return false; |
247 if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK) | 253 if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK) |
248 return false; | 254 return false; |
249 | 255 |
250 return true; | 256 return true; |
251 } | 257 } |
252 | 258 |
253 bool TCPClientSocketLibevent::IsConnectedAndIdle() const { | 259 bool TCPClientSocketLibevent::IsConnectedAndIdle() const { |
| 260 DCHECK(CalledOnValidThread()); |
| 261 |
254 if (socket_ == kInvalidSocket || waiting_connect_) | 262 if (socket_ == kInvalidSocket || waiting_connect_) |
255 return false; | 263 return false; |
256 | 264 |
257 // Check if connection is alive and we haven't received any data | 265 // Check if connection is alive and we haven't received any data |
258 // unexpectedly. | 266 // unexpectedly. |
259 char c; | 267 char c; |
260 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK)); | 268 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK)); |
261 if (rv >= 0) | 269 if (rv >= 0) |
262 return false; | 270 return false; |
263 if (errno != EAGAIN && errno != EWOULDBLOCK) | 271 if (errno != EAGAIN && errno != EWOULDBLOCK) |
264 return false; | 272 return false; |
265 | 273 |
266 return true; | 274 return true; |
267 } | 275 } |
268 | 276 |
269 int TCPClientSocketLibevent::Read(IOBuffer* buf, | 277 int TCPClientSocketLibevent::Read(IOBuffer* buf, |
270 int buf_len, | 278 int buf_len, |
271 CompletionCallback* callback) { | 279 CompletionCallback* callback) { |
| 280 DCHECK(CalledOnValidThread()); |
272 DCHECK_NE(kInvalidSocket, socket_); | 281 DCHECK_NE(kInvalidSocket, socket_); |
273 DCHECK(!waiting_connect_); | 282 DCHECK(!waiting_connect_); |
274 DCHECK(!read_callback_); | 283 DCHECK(!read_callback_); |
275 // Synchronous operation not supported | 284 // Synchronous operation not supported |
276 DCHECK(callback); | 285 DCHECK(callback); |
277 DCHECK_GT(buf_len, 0); | 286 DCHECK_GT(buf_len, 0); |
278 | 287 |
279 TRACE_EVENT_BEGIN("socket.read", this, ""); | 288 TRACE_EVENT_BEGIN("socket.read", this, ""); |
280 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); | 289 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); |
281 if (nread >= 0) { | 290 if (nread >= 0) { |
(...skipping 16 matching lines...) Expand all Loading... |
298 | 307 |
299 read_buf_ = buf; | 308 read_buf_ = buf; |
300 read_buf_len_ = buf_len; | 309 read_buf_len_ = buf_len; |
301 read_callback_ = callback; | 310 read_callback_ = callback; |
302 return ERR_IO_PENDING; | 311 return ERR_IO_PENDING; |
303 } | 312 } |
304 | 313 |
305 int TCPClientSocketLibevent::Write(IOBuffer* buf, | 314 int TCPClientSocketLibevent::Write(IOBuffer* buf, |
306 int buf_len, | 315 int buf_len, |
307 CompletionCallback* callback) { | 316 CompletionCallback* callback) { |
| 317 DCHECK(CalledOnValidThread()); |
308 DCHECK_NE(kInvalidSocket, socket_); | 318 DCHECK_NE(kInvalidSocket, socket_); |
309 DCHECK(!waiting_connect_); | 319 DCHECK(!waiting_connect_); |
310 DCHECK(!write_callback_); | 320 DCHECK(!write_callback_); |
311 // Synchronous operation not supported | 321 // Synchronous operation not supported |
312 DCHECK(callback); | 322 DCHECK(callback); |
313 DCHECK_GT(buf_len, 0); | 323 DCHECK_GT(buf_len, 0); |
314 | 324 |
315 TRACE_EVENT_BEGIN("socket.write", this, ""); | 325 TRACE_EVENT_BEGIN("socket.write", this, ""); |
316 int nwrite = HANDLE_EINTR(write(socket_, buf->data(), buf_len)); | 326 int nwrite = HANDLE_EINTR(write(socket_, buf->data(), buf_len)); |
317 if (nwrite >= 0) { | 327 if (nwrite >= 0) { |
(...skipping 13 matching lines...) Expand all Loading... |
331 } | 341 } |
332 | 342 |
333 | 343 |
334 write_buf_ = buf; | 344 write_buf_ = buf; |
335 write_buf_len_ = buf_len; | 345 write_buf_len_ = buf_len; |
336 write_callback_ = callback; | 346 write_callback_ = callback; |
337 return ERR_IO_PENDING; | 347 return ERR_IO_PENDING; |
338 } | 348 } |
339 | 349 |
340 bool TCPClientSocketLibevent::SetReceiveBufferSize(int32 size) { | 350 bool TCPClientSocketLibevent::SetReceiveBufferSize(int32 size) { |
| 351 DCHECK(CalledOnValidThread()); |
341 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, | 352 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, |
342 reinterpret_cast<const char*>(&size), | 353 reinterpret_cast<const char*>(&size), |
343 sizeof(size)); | 354 sizeof(size)); |
344 DCHECK(!rv) << "Could not set socket receive buffer size: " << errno; | 355 DCHECK(!rv) << "Could not set socket receive buffer size: " << errno; |
345 return rv == 0; | 356 return rv == 0; |
346 } | 357 } |
347 | 358 |
348 bool TCPClientSocketLibevent::SetSendBufferSize(int32 size) { | 359 bool TCPClientSocketLibevent::SetSendBufferSize(int32 size) { |
| 360 DCHECK(CalledOnValidThread()); |
349 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 361 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, |
350 reinterpret_cast<const char*>(&size), | 362 reinterpret_cast<const char*>(&size), |
351 sizeof(size)); | 363 sizeof(size)); |
352 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; | 364 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; |
353 return rv == 0; | 365 return rv == 0; |
354 } | 366 } |
355 | 367 |
356 | 368 |
357 int TCPClientSocketLibevent::CreateSocket(const addrinfo* ai) { | 369 int TCPClientSocketLibevent::CreateSocket(const addrinfo* ai) { |
358 socket_ = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); | 370 socket_ = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 | 482 |
471 if (result != ERR_IO_PENDING) { | 483 if (result != ERR_IO_PENDING) { |
472 write_buf_ = NULL; | 484 write_buf_ = NULL; |
473 write_buf_len_ = 0; | 485 write_buf_len_ = 0; |
474 write_socket_watcher_.StopWatchingFileDescriptor(); | 486 write_socket_watcher_.StopWatchingFileDescriptor(); |
475 DoWriteCallback(result); | 487 DoWriteCallback(result); |
476 } | 488 } |
477 } | 489 } |
478 | 490 |
479 int TCPClientSocketLibevent::GetPeerAddress(AddressList* address) const { | 491 int TCPClientSocketLibevent::GetPeerAddress(AddressList* address) const { |
| 492 DCHECK(CalledOnValidThread()); |
480 DCHECK(address); | 493 DCHECK(address); |
481 if (!current_ai_) | 494 if (!current_ai_) |
482 return ERR_UNEXPECTED; | 495 return ERR_UNEXPECTED; |
483 address->Copy(current_ai_, false); | 496 address->Copy(current_ai_, false); |
484 return OK; | 497 return OK; |
485 } | 498 } |
486 | 499 |
487 } // namespace net | 500 } // namespace net |
OLD | NEW |