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(static_cast<const void*>(kHelloString), | 92 EXPECT_EQ(sync_socket.Send(kHelloString, kHelloStringLength), |
93 kHelloStringLength), kHelloStringLength); | 93 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, size_t* received) { | 209 static void BlockingRead(base::SyncSocket* socket, char* buf, |
| 210 size_t length, size_t* received) { |
| 211 DCHECK(buf != NULL); |
210 // Notify the parent thread that we're up and running. | 212 // Notify the parent thread that we're up and running. |
211 socket->Send(kHelloString, kHelloStringLength); | 213 socket->Send(kHelloString, kHelloStringLength); |
212 char buf[0xff]; // Won't ever be filled. | 214 *received = socket->Receive(buf, length); |
213 *received = socket->Receive(buf, arraysize(buf)); | |
214 } | 215 } |
215 | 216 |
216 // Tests that we can safely end a blocking Receive operation on one thread | 217 // Tests that we can safely end a blocking Receive operation on one thread |
217 // from another thread by disconnecting (but not closing) the socket. | 218 // from another thread by disconnecting (but not closing) the socket. |
218 TEST_F(SyncSocketTest, DisconnectTest) { | 219 TEST_F(SyncSocketTest, DisconnectTest) { |
219 base::CancelableSyncSocket pair[2]; | 220 base::CancelableSyncSocket pair[2]; |
220 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1])); | 221 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1])); |
221 | 222 |
222 base::Thread worker("BlockingThread"); | 223 base::Thread worker("BlockingThread"); |
223 worker.Start(); | 224 worker.Start(); |
224 | 225 |
225 // Try to do a blocking read from one of the sockets on the worker thread. | 226 // Try to do a blocking read from one of the sockets on the worker thread. |
| 227 char buf[0xff]; |
226 size_t received = 1U; // Initialize to an unexpected value. | 228 size_t received = 1U; // Initialize to an unexpected value. |
227 worker.message_loop()->PostTask(FROM_HERE, | 229 worker.message_loop()->PostTask(FROM_HERE, |
228 base::Bind(&BlockingRead, &pair[0], &received)); | 230 base::Bind(&BlockingRead, &pair[0], &buf[0], arraysize(buf), &received)); |
229 | 231 |
230 // Wait for the worker thread to say hello. | 232 // Wait for the worker thread to say hello. |
231 char hello[kHelloStringLength] = {0}; | 233 char hello[kHelloStringLength] = {0}; |
232 pair[1].Receive(&hello[0], sizeof(hello)); | 234 pair[1].Receive(&hello[0], sizeof(hello)); |
233 VLOG(1) << "Received: " << hello; | 235 EXPECT_EQ(0, strcmp(hello, kHelloString)); |
234 // Give the worker a chance to start Receive(). | 236 // Give the worker a chance to start Receive(). |
235 base::PlatformThread::YieldCurrentThread(); | 237 base::PlatformThread::YieldCurrentThread(); |
236 | 238 |
237 // Now shut down the socket that the thread is issuing a blocking read on | 239 // Now shut down the socket that the thread is issuing a blocking read on |
238 // which should cause Receive to return with an error. | 240 // which should cause Receive to return with an error. |
239 pair[0].Shutdown(); | 241 pair[0].Shutdown(); |
240 | 242 |
241 worker.Stop(); | 243 worker.Stop(); |
242 | 244 |
243 EXPECT_EQ(0U, received); | 245 EXPECT_EQ(0U, received); |
244 } | 246 } |
| 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 |