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

Side by Side Diff: net/base/tcp_client_socket_libevent.cc

Issue 13757: message_pump_libevent refactor: (Closed)
Patch Set: Another small fix. Created 12 years 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
OLDNEW
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 "net/base/tcp_client_socket.h" 5 #include "net/base/tcp_client_socket.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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 } 61 }
62 } 62 }
63 63
64 //----------------------------------------------------------------------------- 64 //-----------------------------------------------------------------------------
65 65
66 TCPClientSocket::TCPClientSocket(const AddressList& addresses) 66 TCPClientSocket::TCPClientSocket(const AddressList& addresses)
67 : socket_(kInvalidSocket), 67 : socket_(kInvalidSocket),
68 addresses_(addresses), 68 addresses_(addresses),
69 current_ai_(addresses_.head()), 69 current_ai_(addresses_.head()),
70 waiting_connect_(false), 70 waiting_connect_(false),
71 event_(new event),
72 write_callback_(NULL), 71 write_callback_(NULL),
73 callback_(NULL) { 72 callback_(NULL) {
74 } 73 }
75 74
76 TCPClientSocket::~TCPClientSocket() { 75 TCPClientSocket::~TCPClientSocket() {
77 Disconnect(); 76 Disconnect();
78 } 77 }
79 78
80 int TCPClientSocket::Connect(CompletionCallback* callback) { 79 int TCPClientSocket::Connect(CompletionCallback* callback) {
81 // If already connected, then just return OK. 80 // If already connected, then just return OK.
(...skipping 17 matching lines...) Expand all
99 // Synchronous operation not supported 98 // Synchronous operation not supported
100 DCHECK(callback); 99 DCHECK(callback);
101 100
102 if (errno != EINPROGRESS) { 101 if (errno != EINPROGRESS) {
103 DLOG(INFO) << "connect failed: " << errno; 102 DLOG(INFO) << "connect failed: " << errno;
104 close(socket_); 103 close(socket_);
105 socket_ = kInvalidSocket; 104 socket_ = kInvalidSocket;
106 return MapPosixError(errno); 105 return MapPosixError(errno);
107 } 106 }
108 107
109 // Initialize event_ and link it to our MessagePump. 108 // Initialize socket_watcher_ and link it to our MessagePump.
110 // POLLOUT is set if the connection is established. 109 // POLLOUT is set if the connection is established.
111 // POLLIN is set if the connection fails, 110 // POLLIN is set if the connection fails.
112 // so select for both read and write. 111 if (!MessageLoopForIO::current()->WatchFileDescriptor(
113 MessageLoopForIO::current()->WatchSocket( 112 socket_, true, MessageLoopForIO::WATCH_WRITE, &socket_watcher_,
114 socket_, EV_READ|EV_WRITE|EV_PERSIST, event_.get(), this); 113 this)) {
114 DLOG(INFO) << "WatchFileDescriptor failed: " << errno;
115 close(socket_);
116 socket_ = kInvalidSocket;
117 return MapPosixError(errno);
118 }
115 119
116 waiting_connect_ = true; 120 waiting_connect_ = true;
117 callback_ = callback; 121 callback_ = callback;
118 return ERR_IO_PENDING; 122 return ERR_IO_PENDING;
119 } 123 }
120 124
121 int TCPClientSocket::ReconnectIgnoringLastError(CompletionCallback* callback) { 125 int TCPClientSocket::ReconnectIgnoringLastError(CompletionCallback* callback) {
122 // No ignorable errors! 126 // No ignorable errors!
123 return ERR_UNEXPECTED; 127 return ERR_UNEXPECTED;
124 } 128 }
125 129
126 void TCPClientSocket::Disconnect() { 130 void TCPClientSocket::Disconnect() {
127 if (socket_ == kInvalidSocket) 131 if (socket_ == kInvalidSocket)
128 return; 132 return;
129 133
130 MessageLoopForIO::current()->UnwatchSocket(event_.get()); 134 socket_watcher_.StopWatchingFileDescriptor();
131 close(socket_); 135 close(socket_);
132 socket_ = kInvalidSocket; 136 socket_ = kInvalidSocket;
133 waiting_connect_ = false; 137 waiting_connect_ = false;
134 138
135 // Reset for next time. 139 // Reset for next time.
136 current_ai_ = addresses_.head(); 140 current_ai_ = addresses_.head();
137 } 141 }
138 142
139 bool TCPClientSocket::IsConnected() const { 143 bool TCPClientSocket::IsConnected() const {
140 if (socket_ == kInvalidSocket || waiting_connect_) 144 if (socket_ == kInvalidSocket || waiting_connect_)
(...skipping 22 matching lines...) Expand all
163 167
164 int nread = read(socket_, buf, buf_len); 168 int nread = read(socket_, buf, buf_len);
165 if (nread >= 0) { 169 if (nread >= 0) {
166 return nread; 170 return nread;
167 } 171 }
168 if (errno != EAGAIN && errno != EWOULDBLOCK) { 172 if (errno != EAGAIN && errno != EWOULDBLOCK) {
169 DLOG(INFO) << "read failed, errno " << errno; 173 DLOG(INFO) << "read failed, errno " << errno;
170 return MapPosixError(errno); 174 return MapPosixError(errno);
171 } 175 }
172 176
173 MessageLoopForIO::current()->WatchSocket( 177 if (!MessageLoopForIO::current()->WatchFileDescriptor(
174 socket_, EV_READ|EV_PERSIST, event_.get(), this); 178 socket_, true, MessageLoopForIO::WATCH_READ, &socket_watcher_, this))
179 {
180 DLOG(INFO) << "WatchFileDescriptor failed on read, errno " << errno;
181 return MapPosixError(errno);
182 }
175 183
176 buf_ = buf; 184 buf_ = buf;
177 buf_len_ = buf_len; 185 buf_len_ = buf_len;
178 callback_ = callback; 186 callback_ = callback;
179 return ERR_IO_PENDING; 187 return ERR_IO_PENDING;
180 } 188 }
181 189
182 int TCPClientSocket::Write(const char* buf, 190 int TCPClientSocket::Write(const char* buf,
183 int buf_len, 191 int buf_len,
184 CompletionCallback* callback) { 192 CompletionCallback* callback) {
185 DCHECK(socket_ != kInvalidSocket); 193 DCHECK(socket_ != kInvalidSocket);
186 DCHECK(!waiting_connect_); 194 DCHECK(!waiting_connect_);
187 DCHECK(!write_callback_); 195 DCHECK(!write_callback_);
188 // Synchronous operation not supported 196 // Synchronous operation not supported
189 DCHECK(callback); 197 DCHECK(callback);
190 DCHECK(buf_len > 0); 198 DCHECK(buf_len > 0);
191 199
192 int nwrite = write(socket_, buf, buf_len); 200 int nwrite = write(socket_, buf, buf_len);
193 if (nwrite >= 0) { 201 if (nwrite >= 0) {
194 return nwrite; 202 return nwrite;
195 } 203 }
196 if (errno != EAGAIN && errno != EWOULDBLOCK) 204 if (errno != EAGAIN && errno != EWOULDBLOCK)
197 return MapPosixError(errno); 205 return MapPosixError(errno);
198 206
199 MessageLoopForIO::current()->WatchSocket( 207 if (!MessageLoopForIO::current()->WatchFileDescriptor(
200 socket_, EV_WRITE|EV_PERSIST, event_.get(), this); 208 socket_, true, MessageLoopForIO::WATCH_WRITE, &socket_watcher_, this))
209 {
210 DLOG(INFO) << "WatchFileDescriptor failed on write, errno " << errno;
211 return MapPosixError(errno);
212 }
213
201 214
202 write_buf_ = buf; 215 write_buf_ = buf;
203 write_buf_len_ = buf_len; 216 write_buf_len_ = buf_len;
204 write_callback_ = callback; 217 write_callback_ = callback;
205 return ERR_IO_PENDING; 218 return ERR_IO_PENDING;
206 } 219 }
207 220
208 int TCPClientSocket::CreateSocket(const addrinfo* ai) { 221 int TCPClientSocket::CreateSocket(const addrinfo* ai) {
209 socket_ = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); 222 socket_ = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
210 if (socket_ == kInvalidSocket) 223 if (socket_ == kInvalidSocket)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 error_code == ENETUNREACH || 269 error_code == ENETUNREACH ||
257 error_code == EHOSTUNREACH || 270 error_code == EHOSTUNREACH ||
258 error_code == ETIMEDOUT)) { 271 error_code == ETIMEDOUT)) {
259 // This address failed, try next one in list. 272 // This address failed, try next one in list.
260 const addrinfo* next = current_ai_->ai_next; 273 const addrinfo* next = current_ai_->ai_next;
261 Disconnect(); 274 Disconnect();
262 current_ai_ = next; 275 current_ai_ = next;
263 result = Connect(callback_); 276 result = Connect(callback_);
264 } else { 277 } else {
265 result = MapPosixError(error_code); 278 result = MapPosixError(error_code);
266 MessageLoopForIO::current()->UnwatchSocket(event_.get()); 279 socket_watcher_.StopWatchingFileDescriptor();
267 waiting_connect_ = false; 280 waiting_connect_ = false;
268 } 281 }
269 282
270 if (result != ERR_IO_PENDING) 283 if (result != ERR_IO_PENDING) {
271 DoCallback(result); 284 DoCallback(result);
285 }
272 } 286 }
273 287
274 void TCPClientSocket::DidCompleteRead() { 288 void TCPClientSocket::DidCompleteRead() {
275 int bytes_transferred; 289 int bytes_transferred;
276 bytes_transferred = read(socket_, buf_, buf_len_); 290 bytes_transferred = read(socket_, buf_, buf_len_);
277 291
278 int result; 292 int result;
279 if (bytes_transferred >= 0) { 293 if (bytes_transferred >= 0) {
280 result = bytes_transferred; 294 result = bytes_transferred;
281 } else { 295 } else {
282 result = MapPosixError(errno); 296 result = MapPosixError(errno);
283 } 297 }
284 298
285 if (result != ERR_IO_PENDING) { 299 if (result != ERR_IO_PENDING) {
286 buf_ = NULL; 300 buf_ = NULL;
287 buf_len_ = 0; 301 buf_len_ = 0;
288 MessageLoopForIO::current()->UnwatchSocket(event_.get()); 302 socket_watcher_.StopWatchingFileDescriptor();
289 DoCallback(result); 303 DoCallback(result);
290 } 304 }
291 } 305 }
292 306
293 void TCPClientSocket::DidCompleteWrite() { 307 void TCPClientSocket::DidCompleteWrite() {
294 int bytes_transferred; 308 int bytes_transferred;
295 bytes_transferred = write(socket_, write_buf_, write_buf_len_); 309 bytes_transferred = write(socket_, write_buf_, write_buf_len_);
296 310
297 int result; 311 int result;
298 if (bytes_transferred >= 0) { 312 if (bytes_transferred >= 0) {
299 result = bytes_transferred; 313 result = bytes_transferred;
300 } else { 314 } else {
301 result = MapPosixError(errno); 315 result = MapPosixError(errno);
302 } 316 }
303 317
304 if (result != ERR_IO_PENDING) { 318 if (result != ERR_IO_PENDING) {
305 write_buf_ = NULL; 319 write_buf_ = NULL;
306 write_buf_len_ = 0; 320 write_buf_len_ = 0;
307 MessageLoopForIO::current()->UnwatchSocket(event_.get()); 321 socket_watcher_.StopWatchingFileDescriptor();
308 DoWriteCallback(result); 322 DoWriteCallback(result);
309 } 323 }
310 } 324 }
311 325
312 void TCPClientSocket::OnSocketReady(short flags) { 326 void TCPClientSocket::OnFileCanReadWithoutBlocking(int fd) {
313 // the only used bits of flags are EV_READ and EV_WRITE 327 // When a socket connects it signals both Read and Write, we handle
314 328 // DidCompleteConnect() in the write handler.
315 if (waiting_connect_) { 329 if (!waiting_connect_ && callback_) {
316 DidCompleteConnect(); 330 DidCompleteRead();
317 } else {
318 if ((flags & EV_WRITE) && write_callback_)
319 DidCompleteWrite();
320 if ((flags & EV_READ) && callback_)
321 DidCompleteRead();
322 } 331 }
323 } 332 }
324 333
334 void TCPClientSocket::OnFileCanWriteWithoutBlocking(int fd) {
335 if (waiting_connect_) {
336 DidCompleteConnect();
337 } else if (write_callback_) {
338 DidCompleteWrite();
339 }
340 }
341
325 int TCPClientSocket::GetPeerName(struct sockaddr *name, socklen_t *namelen) { 342 int TCPClientSocket::GetPeerName(struct sockaddr *name, socklen_t *namelen) {
326 return ::getpeername(socket_, name, namelen); 343 return ::getpeername(socket_, name, namelen);
327 } 344 }
328 345
329 } // namespace net 346 } // namespace net
330 347
OLDNEW
« chrome/common/ipc_channel_posix.cc ('K') | « net/base/tcp_client_socket.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698