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

Side by Side Diff: net/base/tcp_client_socket.h

Issue 16549: Add an easy way to do a synchronous connect from test code. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 11 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
« no previous file with comments | « no previous file | net/base/tcp_client_socket_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #ifndef NET_BASE_TCP_CLIENT_SOCKET_H_ 5 #ifndef NET_BASE_TCP_CLIENT_SOCKET_H_
6 #define NET_BASE_TCP_CLIENT_SOCKET_H_ 6 #define NET_BASE_TCP_CLIENT_SOCKET_H_
7 7
8 #include "build/build_config.h" 8 #include "build/build_config.h"
9 9
10 #if defined(OS_WIN) 10 #if defined(OS_WIN)
11 #include <ws2tcpip.h> 11 #include <ws2tcpip.h>
12 #include "base/object_watcher.h" 12 #include "base/object_watcher.h"
13 #elif defined(OS_POSIX) 13 #elif defined(OS_POSIX)
14 struct event; // From libevent 14 struct event; // From libevent
15 #include <sys/socket.h> // for struct sockaddr 15 #include <sys/socket.h> // for struct sockaddr
16 #define SOCKET int 16 #define SOCKET int
17 #include "base/message_loop.h" 17 #include "base/message_loop.h"
18 #endif 18 #endif
19 19
20 #include "base/scoped_ptr.h" 20 #include "base/scoped_ptr.h"
21 #include "base/task.h"
22 #include "base/thread.h"
23 #include "base/waitable_event.h"
21 #include "net/base/address_list.h" 24 #include "net/base/address_list.h"
22 #include "net/base/client_socket.h" 25 #include "net/base/client_socket.h"
23 #include "net/base/completion_callback.h" 26 #include "net/base/completion_callback.h"
27 #include "net/base/net_errors.h"
24 28
25 namespace net { 29 namespace net {
26 30
27 // A client socket that uses TCP as the transport layer. 31 // A client socket that uses TCP as the transport layer.
28 // 32 //
29 // NOTE: The windows implementation supports half duplex only. 33 // NOTE: The windows implementation supports half duplex only.
30 // Read and Write calls must not be in progress at the same time. 34 // Read and Write calls must not be in progress at the same time.
31 // The libevent implementation supports full duplex because that 35 // The libevent implementation supports full duplex because that
32 // made it slightly easier to implement ssl. 36 // made it slightly easier to implement ssl.
33 class TCPClientSocket : public ClientSocket, 37 class TCPClientSocket : public ClientSocket,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 #endif 124 #endif
121 125
122 // External callback; called when read (and on Windows, write) is complete. 126 // External callback; called when read (and on Windows, write) is complete.
123 CompletionCallback* callback_; 127 CompletionCallback* callback_;
124 128
125 int CreateSocket(const struct addrinfo* ai); 129 int CreateSocket(const struct addrinfo* ai);
126 void DoCallback(int rv); 130 void DoCallback(int rv);
127 void DidCompleteConnect(); 131 void DidCompleteConnect();
128 }; 132 };
129 133
134 // Tiny helper class to do a synchronous connect,
135 // in lieu of directly supporting that in TcpClientSocket.
136 // This avoids cluttering the main codepath with code only used by unit tests.
137 // TODO(dkegel): move this to its own header file.
138 class TCPClientSocketSyncConnector
darin (slow to review) 2009/01/08 19:31:09 our convention has been to put testing-only code l
139 : public base::RefCounted<TCPClientSocketSyncConnector> {
140 public:
141 // Connect given socket synchronously.
142 // Returns network error code.
143 static int Connect(net::TCPClientSocket* sock) {
144 // Start up a throwaway IO thread just for this.
145 // TODO(port): use some existing thread pool instead?
146 base::Thread io_thread("SyncConnect");
147 base::Thread::Options options;
148 options.message_loop_type = MessageLoop::TYPE_IO;
149 io_thread.StartWithOptions(options);
150
151 // Post a request to do the connect on that thread.
152 scoped_refptr<TCPClientSocketSyncConnector> connector =
153 new TCPClientSocketSyncConnector(sock);
154 io_thread.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(connector.ge t(),
155 &net::TCPClientSocketSyncConnector::DoConnect));
156 connector->Wait();
157 return connector->GetError();
158 }
159
160 private:
161 // Start a connect. Must be called on an IO thread.
162 void DoConnect() {
163 net_error_ = sock_->Connect(&connect_callback_);
164 if (net_error_ != ERR_IO_PENDING)
165 event_.Signal();
166 }
167
168 // Callback called on same IO thread when connection complete.
169 void ConnectDone(int rv) {
170 net_error_ = rv;
171 event_.Signal();
172 }
173
174 // Call this after posting a call to DoConnect().
175 void Wait() { event_.Wait(); }
176
177 // Call this after Wait() if you need the final error code from the connect.
178 int GetError() { return net_error_; }
179
180 // sock is owned by caller, but must remain valid while this object lives.
181 explicit TCPClientSocketSyncConnector(TCPClientSocket* sock) :
182 event_(false, false),
183 sock_(sock),
184 net_error_(0),
185 connect_callback_(this, &net::TCPClientSocketSyncConnector::ConnectDone) {
186 }
187
188 base::WaitableEvent event_;
189 net::TCPClientSocket* sock_;
190 int net_error_;
191 net::CompletionCallbackImpl<TCPClientSocketSyncConnector> connect_callback_;
192 DISALLOW_COPY_AND_ASSIGN(TCPClientSocketSyncConnector);
193 };
194
130 } // namespace net 195 } // namespace net
131 196
132 #endif // NET_BASE_TCP_CLIENT_SOCKET_H_ 197 #endif // NET_BASE_TCP_CLIENT_SOCKET_H_
133 198
OLDNEW
« no previous file with comments | « no previous file | net/base/tcp_client_socket_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698