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 |
| 210 // A blocking read operation that will block the thread until it receives |
| 211 // |length| bytes of packets or Shutdown() is called on another thread. |
| 212 static void BlockingRead(base::SyncSocket* socket, char* buf, |
| 213 size_t length, size_t* received) { |
| 214 DCHECK(buf != NULL); |
210 // Notify the parent thread that we're up and running. | 215 // Notify the parent thread that we're up and running. |
211 socket->Send(kHelloString, kHelloStringLength); | 216 socket->Send(kHelloString, kHelloStringLength); |
212 char buf[0xff]; // Won't ever be filled. | 217 *received = socket->Receive(buf, length); |
213 *received = socket->Receive(buf, arraysize(buf)); | |
214 } | 218 } |
215 | 219 |
216 // Tests that we can safely end a blocking Receive operation on one thread | 220 // Tests that we can safely end a blocking Receive operation on one thread |
217 // from another thread by disconnecting (but not closing) the socket. | 221 // from another thread by disconnecting (but not closing) the socket. |
218 TEST_F(SyncSocketTest, DisconnectTest) { | 222 TEST_F(SyncSocketTest, DisconnectTest) { |
219 base::CancelableSyncSocket pair[2]; | 223 base::CancelableSyncSocket pair[2]; |
220 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1])); | 224 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1])); |
221 | 225 |
222 base::Thread worker("BlockingThread"); | 226 base::Thread worker("BlockingThread"); |
223 worker.Start(); | 227 worker.Start(); |
224 | 228 |
225 // Try to do a blocking read from one of the sockets on the worker thread. | 229 // Try to do a blocking read from one of the sockets on the worker thread. |
| 230 char buf[0xff]; |
226 size_t received = 1U; // Initialize to an unexpected value. | 231 size_t received = 1U; // Initialize to an unexpected value. |
227 worker.message_loop()->PostTask(FROM_HERE, | 232 worker.message_loop()->PostTask(FROM_HERE, |
228 base::Bind(&BlockingRead, &pair[0], &received)); | 233 base::Bind(&BlockingRead, &pair[0], &buf[0], arraysize(buf), &received)); |
229 | 234 |
230 // Wait for the worker thread to say hello. | 235 // Wait for the worker thread to say hello. |
231 char hello[kHelloStringLength] = {0}; | 236 char hello[kHelloStringLength] = {0}; |
232 pair[1].Receive(&hello[0], sizeof(hello)); | 237 pair[1].Receive(&hello[0], sizeof(hello)); |
233 VLOG(1) << "Received: " << hello; | 238 EXPECT_EQ(0, strcmp(hello, kHelloString)); |
234 // Give the worker a chance to start Receive(). | 239 // Give the worker a chance to start Receive(). |
235 base::PlatformThread::YieldCurrentThread(); | 240 base::PlatformThread::YieldCurrentThread(); |
236 | 241 |
237 // Now shut down the socket that the thread is issuing a blocking read on | 242 // Now shut down the socket that the thread is issuing a blocking read on |
238 // which should cause Receive to return with an error. | 243 // which should cause Receive to return with an error. |
239 pair[0].Shutdown(); | 244 pair[0].Shutdown(); |
240 | 245 |
241 worker.Stop(); | 246 worker.Stop(); |
242 | 247 |
243 EXPECT_EQ(0U, received); | 248 EXPECT_EQ(0U, received); |
244 } | 249 } |
| 250 |
| 251 // Tests that read is a blocking operation. |
| 252 TEST_F(SyncSocketTest, BlockingReceiveTest) { |
| 253 base::CancelableSyncSocket pair[2]; |
| 254 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1])); |
| 255 |
| 256 base::Thread worker("BlockingThread"); |
| 257 worker.Start(); |
| 258 |
| 259 // Try to do a blocking read from one of the sockets on the worker thread. |
| 260 char buf[kHelloStringLength] = {0}; |
| 261 size_t received = 1U; // Initialize to an unexpected value. |
| 262 worker.message_loop()->PostTask(FROM_HERE, |
| 263 base::Bind(&BlockingRead, &pair[0], &buf[0], |
| 264 kHelloStringLength, &received)); |
| 265 |
| 266 // Wait for the worker thread to say hello. |
| 267 char hello[kHelloStringLength] = {0}; |
| 268 pair[1].Receive(&hello[0], sizeof(hello)); |
| 269 EXPECT_EQ(0, strcmp(hello, kHelloString)); |
| 270 // Give the worker a chance to start Receive(). |
| 271 base::PlatformThread::YieldCurrentThread(); |
| 272 |
| 273 // Send a message to the socket on the blocking thead, it should free the |
| 274 // socket from Receive(). |
| 275 pair[1].Send(kHelloString, kHelloStringLength); |
| 276 worker.Stop(); |
| 277 |
| 278 // Verify the socket has received the message. |
| 279 EXPECT_TRUE(strcmp(buf, kHelloString) == 0); |
| 280 EXPECT_EQ(kHelloStringLength, received); |
| 281 } |
| 282 |
| 283 // Tests that the write operation is non-blocking and returns immediately |
| 284 // when there is insufficient space in the socket's buffer. |
| 285 TEST_F(SyncSocketTest, NonBlockingWriteTest) { |
| 286 base::CancelableSyncSocket pair[2]; |
| 287 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1])); |
| 288 |
| 289 // Fill up the buffer for one of the socket, Send() should not block the |
| 290 // thread even when the buffer is full. |
| 291 while (pair[0].Send(kHelloString, kHelloStringLength) != 0) {} |
| 292 |
| 293 // Data should be avialble on another socket. |
| 294 size_t bytes_in_buffer = pair[1].Peek(); |
| 295 EXPECT_NE(bytes_in_buffer, 0U); |
| 296 |
| 297 // No more data can be written to the buffer since socket has been full, |
| 298 // verify that the amount of avialble data on another socket is unchanged. |
| 299 EXPECT_EQ(0U, pair[0].Send(kHelloString, kHelloStringLength)); |
| 300 EXPECT_EQ(bytes_in_buffer, pair[1].Peek()); |
| 301 |
| 302 // Read from another socket to free some space for a new write. |
| 303 char hello[kHelloStringLength] = {0}; |
| 304 pair[1].Receive(&hello[0], sizeof(hello)); |
| 305 |
| 306 // Should be able to write more data to the buffer now. |
| 307 EXPECT_EQ(kHelloStringLength, pair[0].Send(kHelloString, kHelloStringLength)); |
| 308 } |
OLD | NEW |