OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/sync_socket.h" | 5 #include "base/sync_socket.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 #include <string> | 8 #include <string> |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 #elif defined(OS_POSIX) | 82 #elif defined(OS_POSIX) |
83 void OnMsgClassSetHandle(const base::FileDescriptor& fd_struct) { | 83 void OnMsgClassSetHandle(const base::FileDescriptor& fd_struct) { |
84 SetHandle(fd_struct.fd); | 84 SetHandle(fd_struct.fd); |
85 } | 85 } |
86 #else | 86 #else |
87 # error "What platform?" | 87 # error "What platform?" |
88 #endif // defined(OS_WIN) | 88 #endif // defined(OS_WIN) |
89 | 89 |
90 void SetHandle(base::SyncSocket::Handle handle) { | 90 void SetHandle(base::SyncSocket::Handle handle) { |
91 base::SyncSocket sync_socket(handle); | 91 base::SyncSocket sync_socket(handle); |
92 EXPECT_EQ(sync_socket.Send(kHelloString, kHelloStringLength), | 92 EXPECT_EQ(sync_socket.Send(static_cast<const void*>(kHelloString), |
93 kHelloStringLength); | 93 kHelloStringLength), kHelloStringLength); |
94 IPC::Message* msg = new MsgClassResponse(kHelloString); | 94 IPC::Message* msg = new MsgClassResponse(kHelloString); |
95 EXPECT_TRUE(chan_->Send(msg)); | 95 EXPECT_TRUE(chan_->Send(msg)); |
96 } | 96 } |
97 | 97 |
98 // When the client responds, it sends back a shutdown message, | 98 // When the client responds, it sends back a shutdown message, |
99 // which causes the message loop to exit. | 99 // which causes the message loop to exit. |
100 void OnMsgClassShutdown() { | 100 void OnMsgClassShutdown() { |
101 MessageLoop::current()->Quit(); | 101 MessageLoop::current()->Quit(); |
102 } | 102 } |
103 | 103 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 EXPECT_TRUE(chan.Send(msg)); | 199 EXPECT_TRUE(chan.Send(msg)); |
200 // Use the current thread as the I/O thread. | 200 // Use the current thread as the I/O thread. |
201 MessageLoop::current()->Run(); | 201 MessageLoop::current()->Run(); |
202 // Shut down. | 202 // Shut down. |
203 pair[0].Close(); | 203 pair[0].Close(); |
204 pair[1].Close(); | 204 pair[1].Close(); |
205 EXPECT_TRUE(base::WaitForSingleProcess(server_process, 5000)); | 205 EXPECT_TRUE(base::WaitForSingleProcess(server_process, 5000)); |
206 base::CloseProcessHandle(server_process); | 206 base::CloseProcessHandle(server_process); |
207 } | 207 } |
208 | 208 |
209 static void BlockingRead(base::SyncSocket* socket, char* buf, | 209 static void BlockingRead(base::SyncSocket* socket, size_t* received) { |
210 size_t length, size_t* received) { | |
211 DCHECK(buf != NULL); | |
212 // Notify the parent thread that we're up and running. | 210 // Notify the parent thread that we're up and running. |
213 socket->Send(kHelloString, kHelloStringLength); | 211 socket->Send(kHelloString, kHelloStringLength); |
214 *received = socket->Receive(buf, length); | 212 char buf[0xff]; // Won't ever be filled. |
| 213 *received = socket->Receive(buf, arraysize(buf)); |
215 } | 214 } |
216 | 215 |
217 // Tests that we can safely end a blocking Receive operation on one thread | 216 // Tests that we can safely end a blocking Receive operation on one thread |
218 // from another thread by disconnecting (but not closing) the socket. | 217 // from another thread by disconnecting (but not closing) the socket. |
219 TEST_F(SyncSocketTest, DisconnectTest) { | 218 TEST_F(SyncSocketTest, DisconnectTest) { |
220 base::CancelableSyncSocket pair[2]; | 219 base::CancelableSyncSocket pair[2]; |
221 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1])); | 220 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1])); |
222 | 221 |
223 base::Thread worker("BlockingThread"); | 222 base::Thread worker("BlockingThread"); |
224 worker.Start(); | 223 worker.Start(); |
225 | 224 |
226 // Try to do a blocking read from one of the sockets on the worker thread. | 225 // Try to do a blocking read from one of the sockets on the worker thread. |
227 char buf[0xff]; | |
228 size_t received = 1U; // Initialize to an unexpected value. | 226 size_t received = 1U; // Initialize to an unexpected value. |
229 worker.message_loop()->PostTask(FROM_HERE, | 227 worker.message_loop()->PostTask(FROM_HERE, |
230 base::Bind(&BlockingRead, &pair[0], &buf[0], arraysize(buf), &received)); | 228 base::Bind(&BlockingRead, &pair[0], &received)); |
231 | 229 |
232 // Wait for the worker thread to say hello. | 230 // Wait for the worker thread to say hello. |
233 char hello[kHelloStringLength] = {0}; | 231 char hello[kHelloStringLength] = {0}; |
234 pair[1].Receive(&hello[0], sizeof(hello)); | 232 pair[1].Receive(&hello[0], sizeof(hello)); |
235 EXPECT_EQ(0, strcmp(hello, kHelloString)); | 233 VLOG(1) << "Received: " << hello; |
236 // Give the worker a chance to start Receive(). | 234 // Give the worker a chance to start Receive(). |
237 base::PlatformThread::YieldCurrentThread(); | 235 base::PlatformThread::YieldCurrentThread(); |
238 | 236 |
239 // Now shut down the socket that the thread is issuing a blocking read on | 237 // Now shut down the socket that the thread is issuing a blocking read on |
240 // which should cause Receive to return with an error. | 238 // which should cause Receive to return with an error. |
241 pair[0].Shutdown(); | 239 pair[0].Shutdown(); |
242 | 240 |
243 worker.Stop(); | 241 worker.Stop(); |
244 | 242 |
245 EXPECT_EQ(0U, received); | 243 EXPECT_EQ(0U, received); |
246 } | 244 } |
247 | |
248 // Tests that read is a blocking operation. | |
249 TEST_F(SyncSocketTest, BlockingReceiveTest) { | |
250 base::CancelableSyncSocket pair[2]; | |
251 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1])); | |
252 | |
253 base::Thread worker("BlockingThread"); | |
254 worker.Start(); | |
255 | |
256 // Try to do a blocking read from one of the sockets on the worker thread. | |
257 char buf[kHelloStringLength] = {0}; | |
258 size_t received = 1U; // Initialize to an unexpected value. | |
259 worker.message_loop()->PostTask(FROM_HERE, | |
260 base::Bind(&BlockingRead, &pair[0], &buf[0], | |
261 kHelloStringLength, &received)); | |
262 | |
263 // Wait for the worker thread to say hello. | |
264 char hello[kHelloStringLength] = {0}; | |
265 pair[1].Receive(&hello[0], sizeof(hello)); | |
266 EXPECT_EQ(0, strcmp(hello, kHelloString)); | |
267 // Give the worker a chance to start Receive(). | |
268 base::PlatformThread::YieldCurrentThread(); | |
269 | |
270 // The socket on the blocking thread is currently blocked on Receive() and | |
271 // has got nothing. | |
272 EXPECT_EQ(1U, received); | |
273 | |
274 // Send a message to the socket on the blocking thead, it should free the | |
275 // socket from Receive(). | |
276 pair[1].Send(kHelloString, kHelloStringLength); | |
277 worker.Stop(); | |
278 | |
279 // Verify the socket has received the message. | |
280 EXPECT_TRUE(strcmp(buf, kHelloString) == 0); | |
281 EXPECT_EQ(kHelloStringLength, received); | |
282 } | |
283 | |
284 // Tests that the write operation is non-blocking and returns immediately | |
285 // when there is insufficient space in the socket's buffer. | |
286 TEST_F(SyncSocketTest, NonBlockingWriteTest) { | |
287 base::CancelableSyncSocket pair[2]; | |
288 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1])); | |
289 | |
290 // Fill up the buffer for one of the socket, Send() should not block the | |
291 // thread even when the buffer is full. | |
292 while (pair[0].Send(kHelloString, kHelloStringLength) != 0) {} | |
293 | |
294 // Data should be avialble on another socket. | |
295 size_t bytes_in_buffer = pair[1].Peek(); | |
296 EXPECT_NE(bytes_in_buffer, 0U); | |
297 | |
298 // No more data can be written to the buffer since socket has been full, | |
299 // verify that the amount of avialble data on another socket is unchanged. | |
300 EXPECT_EQ(0U, pair[0].Send(kHelloString, kHelloStringLength)); | |
301 EXPECT_EQ(bytes_in_buffer, pair[1].Peek()); | |
302 | |
303 // Read from another socket to free some space for a new write. | |
304 char hello[kHelloStringLength] = {0}; | |
305 pair[1].Receive(&hello[0], sizeof(hello)); | |
306 | |
307 // Should be able to write more data to the buffer now. | |
308 EXPECT_EQ(kHelloStringLength, pair[0].Send(kHelloString, kHelloStringLength)); | |
309 } | |
OLD | NEW |