| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "mojo/edk/system/message_pipe.h" | |
| 6 | |
| 7 #include "base/memory/ref_counted.h" | |
| 8 #include "base/threading/platform_thread.h" // For |Sleep()|. | |
| 9 #include "base/time/time.h" | |
| 10 #include "mojo/edk/system/waiter.h" | |
| 11 #include "mojo/edk/system/waiter_test_utils.h" | |
| 12 #include "testing/gtest/include/gtest/gtest.h" | |
| 13 | |
| 14 namespace mojo { | |
| 15 namespace system { | |
| 16 namespace { | |
| 17 | |
| 18 const MojoHandleSignals kAllSignals = MOJO_HANDLE_SIGNAL_READABLE | | |
| 19 MOJO_HANDLE_SIGNAL_WRITABLE | | |
| 20 MOJO_HANDLE_SIGNAL_PEER_CLOSED; | |
| 21 | |
| 22 // Tests: | |
| 23 // - only default flags | |
| 24 // - reading messages from a port | |
| 25 // - when there are no/one/two messages available for that port | |
| 26 // - with buffer size 0 (and null buffer) -- should get size | |
| 27 // - with too-small buffer -- should get size | |
| 28 // - also verify that buffers aren't modified when/where they shouldn't be | |
| 29 // - writing messages to a port | |
| 30 // - in the obvious scenarios (as above) | |
| 31 // - to a port that's been closed | |
| 32 // - writing a message to a port, closing the other (would be the source) port, | |
| 33 // and reading it | |
| 34 TEST(MessagePipeTest, Basic) { | |
| 35 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
| 36 | |
| 37 int32_t buffer[2]; | |
| 38 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | |
| 39 uint32_t buffer_size; | |
| 40 | |
| 41 // Nothing to read yet on port 0. | |
| 42 buffer[0] = 123; | |
| 43 buffer[1] = 456; | |
| 44 buffer_size = kBufferSize; | |
| 45 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
| 46 mp->ReadMessage(0, UserPointer<void>(buffer), | |
| 47 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 48 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 49 EXPECT_EQ(kBufferSize, buffer_size); | |
| 50 EXPECT_EQ(123, buffer[0]); | |
| 51 EXPECT_EQ(456, buffer[1]); | |
| 52 | |
| 53 // Ditto for port 1. | |
| 54 buffer[0] = 123; | |
| 55 buffer[1] = 456; | |
| 56 buffer_size = kBufferSize; | |
| 57 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
| 58 mp->ReadMessage(1, UserPointer<void>(buffer), | |
| 59 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 60 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 61 | |
| 62 // Write from port 1 (to port 0). | |
| 63 buffer[0] = 789012345; | |
| 64 buffer[1] = 0; | |
| 65 EXPECT_EQ(MOJO_RESULT_OK, | |
| 66 mp->WriteMessage(1, UserPointer<const void>(buffer), | |
| 67 static_cast<uint32_t>(sizeof(buffer[0])), nullptr, | |
| 68 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 69 | |
| 70 // Read from port 0. | |
| 71 buffer[0] = 123; | |
| 72 buffer[1] = 456; | |
| 73 buffer_size = kBufferSize; | |
| 74 EXPECT_EQ(MOJO_RESULT_OK, | |
| 75 mp->ReadMessage(0, UserPointer<void>(buffer), | |
| 76 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 77 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 78 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
| 79 EXPECT_EQ(789012345, buffer[0]); | |
| 80 EXPECT_EQ(456, buffer[1]); | |
| 81 | |
| 82 // Read again from port 0 -- it should be empty. | |
| 83 buffer_size = kBufferSize; | |
| 84 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
| 85 mp->ReadMessage(0, UserPointer<void>(buffer), | |
| 86 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 87 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 88 | |
| 89 // Write two messages from port 0 (to port 1). | |
| 90 buffer[0] = 123456789; | |
| 91 buffer[1] = 0; | |
| 92 EXPECT_EQ(MOJO_RESULT_OK, | |
| 93 mp->WriteMessage(0, UserPointer<const void>(buffer), | |
| 94 static_cast<uint32_t>(sizeof(buffer[0])), nullptr, | |
| 95 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 96 buffer[0] = 234567890; | |
| 97 buffer[1] = 0; | |
| 98 EXPECT_EQ(MOJO_RESULT_OK, | |
| 99 mp->WriteMessage(0, UserPointer<const void>(buffer), | |
| 100 static_cast<uint32_t>(sizeof(buffer[0])), nullptr, | |
| 101 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 102 | |
| 103 // Read from port 1 with buffer size 0 (should get the size of next message). | |
| 104 // Also test that giving a null buffer is okay when the buffer size is 0. | |
| 105 buffer_size = 0; | |
| 106 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
| 107 mp->ReadMessage(1, NullUserPointer(), MakeUserPointer(&buffer_size), | |
| 108 0, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 109 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
| 110 | |
| 111 // Read from port 1 with buffer size 1 (too small; should get the size of next | |
| 112 // message). | |
| 113 buffer[0] = 123; | |
| 114 buffer[1] = 456; | |
| 115 buffer_size = 1; | |
| 116 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
| 117 mp->ReadMessage(1, UserPointer<void>(buffer), | |
| 118 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 119 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 120 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
| 121 EXPECT_EQ(123, buffer[0]); | |
| 122 EXPECT_EQ(456, buffer[1]); | |
| 123 | |
| 124 // Read from port 1. | |
| 125 buffer[0] = 123; | |
| 126 buffer[1] = 456; | |
| 127 buffer_size = kBufferSize; | |
| 128 EXPECT_EQ(MOJO_RESULT_OK, | |
| 129 mp->ReadMessage(1, UserPointer<void>(buffer), | |
| 130 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 131 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 132 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
| 133 EXPECT_EQ(123456789, buffer[0]); | |
| 134 EXPECT_EQ(456, buffer[1]); | |
| 135 | |
| 136 // Read again from port 1. | |
| 137 buffer[0] = 123; | |
| 138 buffer[1] = 456; | |
| 139 buffer_size = kBufferSize; | |
| 140 EXPECT_EQ(MOJO_RESULT_OK, | |
| 141 mp->ReadMessage(1, UserPointer<void>(buffer), | |
| 142 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 143 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 144 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
| 145 EXPECT_EQ(234567890, buffer[0]); | |
| 146 EXPECT_EQ(456, buffer[1]); | |
| 147 | |
| 148 // Read again from port 1 -- it should be empty. | |
| 149 buffer_size = kBufferSize; | |
| 150 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
| 151 mp->ReadMessage(1, UserPointer<void>(buffer), | |
| 152 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 153 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 154 | |
| 155 // Write from port 0 (to port 1). | |
| 156 buffer[0] = 345678901; | |
| 157 buffer[1] = 0; | |
| 158 EXPECT_EQ(MOJO_RESULT_OK, | |
| 159 mp->WriteMessage(0, UserPointer<const void>(buffer), | |
| 160 static_cast<uint32_t>(sizeof(buffer[0])), nullptr, | |
| 161 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 162 | |
| 163 // Close port 0. | |
| 164 mp->Close(0); | |
| 165 | |
| 166 // Try to write from port 1 (to port 0). | |
| 167 buffer[0] = 456789012; | |
| 168 buffer[1] = 0; | |
| 169 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
| 170 mp->WriteMessage(1, UserPointer<const void>(buffer), | |
| 171 static_cast<uint32_t>(sizeof(buffer[0])), nullptr, | |
| 172 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 173 | |
| 174 // Read from port 1; should still get message (even though port 0 was closed). | |
| 175 buffer[0] = 123; | |
| 176 buffer[1] = 456; | |
| 177 buffer_size = kBufferSize; | |
| 178 EXPECT_EQ(MOJO_RESULT_OK, | |
| 179 mp->ReadMessage(1, UserPointer<void>(buffer), | |
| 180 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 181 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 182 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
| 183 EXPECT_EQ(345678901, buffer[0]); | |
| 184 EXPECT_EQ(456, buffer[1]); | |
| 185 | |
| 186 // Read again from port 1 -- it should be empty (and port 0 is closed). | |
| 187 buffer_size = kBufferSize; | |
| 188 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
| 189 mp->ReadMessage(1, UserPointer<void>(buffer), | |
| 190 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 191 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 192 | |
| 193 mp->Close(1); | |
| 194 } | |
| 195 | |
| 196 TEST(MessagePipeTest, CloseWithQueuedIncomingMessages) { | |
| 197 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
| 198 | |
| 199 int32_t buffer[1]; | |
| 200 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | |
| 201 uint32_t buffer_size; | |
| 202 | |
| 203 // Write some messages from port 1 (to port 0). | |
| 204 for (int32_t i = 0; i < 5; i++) { | |
| 205 buffer[0] = i; | |
| 206 EXPECT_EQ(MOJO_RESULT_OK, | |
| 207 mp->WriteMessage(1, UserPointer<const void>(buffer), kBufferSize, | |
| 208 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 209 } | |
| 210 | |
| 211 // Port 0 shouldn't be empty. | |
| 212 buffer_size = 0; | |
| 213 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
| 214 mp->ReadMessage(0, NullUserPointer(), MakeUserPointer(&buffer_size), | |
| 215 0, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 216 EXPECT_EQ(kBufferSize, buffer_size); | |
| 217 | |
| 218 // Close port 0 first, which should have outstanding (incoming) messages. | |
| 219 mp->Close(0); | |
| 220 mp->Close(1); | |
| 221 } | |
| 222 | |
| 223 TEST(MessagePipeTest, DiscardMode) { | |
| 224 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
| 225 | |
| 226 int32_t buffer[2]; | |
| 227 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | |
| 228 uint32_t buffer_size; | |
| 229 | |
| 230 // Write from port 1 (to port 0). | |
| 231 buffer[0] = 789012345; | |
| 232 buffer[1] = 0; | |
| 233 EXPECT_EQ(MOJO_RESULT_OK, | |
| 234 mp->WriteMessage(1, UserPointer<const void>(buffer), | |
| 235 static_cast<uint32_t>(sizeof(buffer[0])), nullptr, | |
| 236 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 237 | |
| 238 // Read/discard from port 0 (no buffer); get size. | |
| 239 buffer_size = 0; | |
| 240 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
| 241 mp->ReadMessage(0, NullUserPointer(), MakeUserPointer(&buffer_size), | |
| 242 0, nullptr, MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
| 243 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
| 244 | |
| 245 // Read again from port 0 -- it should be empty. | |
| 246 buffer_size = kBufferSize; | |
| 247 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
| 248 mp->ReadMessage(0, UserPointer<void>(buffer), | |
| 249 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 250 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
| 251 | |
| 252 // Write from port 1 (to port 0). | |
| 253 buffer[0] = 890123456; | |
| 254 buffer[1] = 0; | |
| 255 EXPECT_EQ(MOJO_RESULT_OK, | |
| 256 mp->WriteMessage(1, UserPointer<const void>(buffer), | |
| 257 static_cast<uint32_t>(sizeof(buffer[0])), nullptr, | |
| 258 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 259 | |
| 260 // Read from port 0 (buffer big enough). | |
| 261 buffer[0] = 123; | |
| 262 buffer[1] = 456; | |
| 263 buffer_size = kBufferSize; | |
| 264 EXPECT_EQ(MOJO_RESULT_OK, | |
| 265 mp->ReadMessage(0, UserPointer<void>(buffer), | |
| 266 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 267 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
| 268 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
| 269 EXPECT_EQ(890123456, buffer[0]); | |
| 270 EXPECT_EQ(456, buffer[1]); | |
| 271 | |
| 272 // Read again from port 0 -- it should be empty. | |
| 273 buffer_size = kBufferSize; | |
| 274 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
| 275 mp->ReadMessage(0, UserPointer<void>(buffer), | |
| 276 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 277 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
| 278 | |
| 279 // Write from port 1 (to port 0). | |
| 280 buffer[0] = 901234567; | |
| 281 buffer[1] = 0; | |
| 282 EXPECT_EQ(MOJO_RESULT_OK, | |
| 283 mp->WriteMessage(1, UserPointer<const void>(buffer), | |
| 284 static_cast<uint32_t>(sizeof(buffer[0])), nullptr, | |
| 285 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 286 | |
| 287 // Read/discard from port 0 (buffer too small); get size. | |
| 288 buffer_size = 1; | |
| 289 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
| 290 mp->ReadMessage(0, UserPointer<void>(buffer), | |
| 291 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 292 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
| 293 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
| 294 | |
| 295 // Read again from port 0 -- it should be empty. | |
| 296 buffer_size = kBufferSize; | |
| 297 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
| 298 mp->ReadMessage(0, UserPointer<void>(buffer), | |
| 299 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 300 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
| 301 | |
| 302 // Write from port 1 (to port 0). | |
| 303 buffer[0] = 123456789; | |
| 304 buffer[1] = 0; | |
| 305 EXPECT_EQ(MOJO_RESULT_OK, | |
| 306 mp->WriteMessage(1, UserPointer<const void>(buffer), | |
| 307 static_cast<uint32_t>(sizeof(buffer[0])), nullptr, | |
| 308 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 309 | |
| 310 // Discard from port 0. | |
| 311 buffer_size = 1; | |
| 312 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
| 313 mp->ReadMessage(0, NullUserPointer(), NullUserPointer(), 0, nullptr, | |
| 314 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
| 315 | |
| 316 // Read again from port 0 -- it should be empty. | |
| 317 buffer_size = kBufferSize; | |
| 318 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
| 319 mp->ReadMessage(0, UserPointer<void>(buffer), | |
| 320 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 321 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
| 322 | |
| 323 mp->Close(0); | |
| 324 mp->Close(1); | |
| 325 } | |
| 326 | |
| 327 TEST(MessagePipeTest, BasicWaiting) { | |
| 328 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
| 329 Waiter waiter; | |
| 330 HandleSignalsState hss; | |
| 331 | |
| 332 int32_t buffer[1]; | |
| 333 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | |
| 334 uint32_t buffer_size; | |
| 335 | |
| 336 // Always writable (until the other port is closed). | |
| 337 waiter.Init(); | |
| 338 hss = HandleSignalsState(); | |
| 339 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | |
| 340 mp->AddAwakable(0, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss)); | |
| 341 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); | |
| 342 EXPECT_EQ(kAllSignals, hss.satisfiable_signals); | |
| 343 waiter.Init(); | |
| 344 hss = HandleSignalsState(); | |
| 345 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | |
| 346 mp->AddAwakable(0, &waiter, MOJO_HANDLE_SIGNAL_READABLE | | |
| 347 MOJO_HANDLE_SIGNAL_WRITABLE, | |
| 348 0, &hss)); | |
| 349 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); | |
| 350 EXPECT_EQ(kAllSignals, hss.satisfiable_signals); | |
| 351 | |
| 352 // Not yet readable. | |
| 353 waiter.Init(); | |
| 354 ASSERT_EQ( | |
| 355 MOJO_RESULT_OK, | |
| 356 mp->AddAwakable(0, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 1, nullptr)); | |
| 357 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr)); | |
| 358 hss = HandleSignalsState(); | |
| 359 mp->RemoveAwakable(0, &waiter, &hss); | |
| 360 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); | |
| 361 EXPECT_EQ(kAllSignals, hss.satisfiable_signals); | |
| 362 | |
| 363 // The peer is not closed. | |
| 364 waiter.Init(); | |
| 365 ASSERT_EQ( | |
| 366 MOJO_RESULT_OK, | |
| 367 mp->AddAwakable(0, &waiter, MOJO_HANDLE_SIGNAL_PEER_CLOSED, 2, nullptr)); | |
| 368 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr)); | |
| 369 hss = HandleSignalsState(); | |
| 370 mp->RemoveAwakable(0, &waiter, &hss); | |
| 371 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); | |
| 372 EXPECT_EQ(kAllSignals, hss.satisfiable_signals); | |
| 373 | |
| 374 // Write from port 0 (to port 1), to make port 1 readable. | |
| 375 buffer[0] = 123456789; | |
| 376 EXPECT_EQ(MOJO_RESULT_OK, | |
| 377 mp->WriteMessage(0, UserPointer<const void>(buffer), kBufferSize, | |
| 378 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 379 | |
| 380 // Port 1 should already be readable now. | |
| 381 waiter.Init(); | |
| 382 hss = HandleSignalsState(); | |
| 383 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | |
| 384 mp->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 3, &hss)); | |
| 385 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
| 386 hss.satisfied_signals); | |
| 387 EXPECT_EQ(kAllSignals, hss.satisfiable_signals); | |
| 388 waiter.Init(); | |
| 389 hss = HandleSignalsState(); | |
| 390 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | |
| 391 mp->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE | | |
| 392 MOJO_HANDLE_SIGNAL_WRITABLE, | |
| 393 0, &hss)); | |
| 394 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
| 395 hss.satisfied_signals); | |
| 396 EXPECT_EQ(kAllSignals, hss.satisfiable_signals); | |
| 397 // ... and still writable. | |
| 398 waiter.Init(); | |
| 399 hss = HandleSignalsState(); | |
| 400 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | |
| 401 mp->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 4, &hss)); | |
| 402 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
| 403 hss.satisfied_signals); | |
| 404 EXPECT_EQ(kAllSignals, hss.satisfiable_signals); | |
| 405 | |
| 406 // Close port 0. | |
| 407 mp->Close(0); | |
| 408 | |
| 409 // Port 1 should be signaled with peer closed. | |
| 410 waiter.Init(); | |
| 411 hss = HandleSignalsState(); | |
| 412 EXPECT_EQ( | |
| 413 MOJO_RESULT_ALREADY_EXISTS, | |
| 414 mp->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_PEER_CLOSED, 5, &hss)); | |
| 415 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
| 416 hss.satisfied_signals); | |
| 417 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
| 418 hss.satisfiable_signals); | |
| 419 | |
| 420 // Port 1 should not be writable. | |
| 421 waiter.Init(); | |
| 422 hss = HandleSignalsState(); | |
| 423 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
| 424 mp->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 6, &hss)); | |
| 425 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
| 426 hss.satisfied_signals); | |
| 427 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
| 428 hss.satisfiable_signals); | |
| 429 | |
| 430 // But it should still be readable. | |
| 431 waiter.Init(); | |
| 432 hss = HandleSignalsState(); | |
| 433 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | |
| 434 mp->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 7, &hss)); | |
| 435 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
| 436 hss.satisfied_signals); | |
| 437 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, | |
| 438 hss.satisfiable_signals); | |
| 439 | |
| 440 // Read from port 1. | |
| 441 buffer[0] = 0; | |
| 442 buffer_size = kBufferSize; | |
| 443 EXPECT_EQ(MOJO_RESULT_OK, | |
| 444 mp->ReadMessage(1, UserPointer<void>(buffer), | |
| 445 MakeUserPointer(&buffer_size), 0, nullptr, | |
| 446 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 447 EXPECT_EQ(123456789, buffer[0]); | |
| 448 | |
| 449 // Now port 1 should no longer be readable. | |
| 450 waiter.Init(); | |
| 451 hss = HandleSignalsState(); | |
| 452 EXPECT_EQ( | |
| 453 MOJO_RESULT_FAILED_PRECONDITION, | |
| 454 mp->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 8, nullptr)); | |
| 455 EXPECT_EQ(0u, hss.satisfied_signals); | |
| 456 EXPECT_EQ(0u, hss.satisfiable_signals); | |
| 457 | |
| 458 mp->Close(1); | |
| 459 } | |
| 460 | |
| 461 TEST(MessagePipeTest, ThreadedWaiting) { | |
| 462 int32_t buffer[1]; | |
| 463 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | |
| 464 | |
| 465 MojoResult result; | |
| 466 uint32_t context; | |
| 467 | |
| 468 // Write to wake up waiter waiting for read. | |
| 469 { | |
| 470 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
| 471 test::SimpleWaiterThread thread(&result, &context); | |
| 472 | |
| 473 thread.waiter()->Init(); | |
| 474 ASSERT_EQ(MOJO_RESULT_OK, | |
| 475 mp->AddAwakable(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, | |
| 476 1, nullptr)); | |
| 477 thread.Start(); | |
| 478 | |
| 479 buffer[0] = 123456789; | |
| 480 // Write from port 0 (to port 1), which should wake up the waiter. | |
| 481 EXPECT_EQ(MOJO_RESULT_OK, | |
| 482 mp->WriteMessage(0, UserPointer<const void>(buffer), kBufferSize, | |
| 483 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 484 | |
| 485 HandleSignalsState hss; | |
| 486 mp->RemoveAwakable(1, thread.waiter(), &hss); | |
| 487 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
| 488 hss.satisfied_signals); | |
| 489 EXPECT_EQ(kAllSignals, hss.satisfiable_signals); | |
| 490 | |
| 491 mp->Close(0); | |
| 492 mp->Close(1); | |
| 493 } // Joins |thread|. | |
| 494 // The waiter should have woken up successfully. | |
| 495 EXPECT_EQ(MOJO_RESULT_OK, result); | |
| 496 EXPECT_EQ(1u, context); | |
| 497 | |
| 498 // Close to cancel waiter. | |
| 499 { | |
| 500 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
| 501 test::SimpleWaiterThread thread(&result, &context); | |
| 502 | |
| 503 thread.waiter()->Init(); | |
| 504 ASSERT_EQ(MOJO_RESULT_OK, | |
| 505 mp->AddAwakable(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, | |
| 506 2, nullptr)); | |
| 507 thread.Start(); | |
| 508 | |
| 509 // Close port 1 first -- this should result in the waiter being cancelled. | |
| 510 mp->CancelAllAwakables(1); | |
| 511 mp->Close(1); | |
| 512 | |
| 513 // Port 1 is closed, so |Dispatcher::RemoveAwakable()| wouldn't call into | |
| 514 // the |MessagePipe| to remove any waiter. | |
| 515 | |
| 516 mp->Close(0); | |
| 517 } // Joins |thread|. | |
| 518 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | |
| 519 EXPECT_EQ(2u, context); | |
| 520 | |
| 521 // Close to cancel waiter using peer closed signal. | |
| 522 { | |
| 523 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
| 524 test::SimpleWaiterThread thread(&result, &context); | |
| 525 | |
| 526 thread.waiter()->Init(); | |
| 527 ASSERT_EQ(MOJO_RESULT_OK, | |
| 528 mp->AddAwakable(1, thread.waiter(), | |
| 529 MOJO_HANDLE_SIGNAL_PEER_CLOSED, 3, nullptr)); | |
| 530 thread.Start(); | |
| 531 | |
| 532 // Close port 1 first -- this should result in the waiter being cancelled. | |
| 533 mp->CancelAllAwakables(1); | |
| 534 mp->Close(1); | |
| 535 | |
| 536 // Port 1 is closed, so |Dispatcher::RemoveAwakable()| wouldn't call into | |
| 537 // the |MessagePipe| to remove any waiter. | |
| 538 | |
| 539 mp->Close(0); | |
| 540 } // Joins |thread|. | |
| 541 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | |
| 542 EXPECT_EQ(3u, context); | |
| 543 | |
| 544 // Close to make waiter un-wake-up-able. | |
| 545 { | |
| 546 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
| 547 test::SimpleWaiterThread thread(&result, &context); | |
| 548 | |
| 549 thread.waiter()->Init(); | |
| 550 ASSERT_EQ(MOJO_RESULT_OK, | |
| 551 mp->AddAwakable(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, | |
| 552 4, nullptr)); | |
| 553 thread.Start(); | |
| 554 | |
| 555 // Close port 0 first -- this should wake the waiter up, since port 1 will | |
| 556 // never be readable. | |
| 557 mp->CancelAllAwakables(0); | |
| 558 mp->Close(0); | |
| 559 | |
| 560 HandleSignalsState hss; | |
| 561 mp->RemoveAwakable(1, thread.waiter(), &hss); | |
| 562 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals); | |
| 563 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); | |
| 564 | |
| 565 mp->CancelAllAwakables(1); | |
| 566 mp->Close(1); | |
| 567 } // Joins |thread|. | |
| 568 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | |
| 569 EXPECT_EQ(4u, context); | |
| 570 } | |
| 571 | |
| 572 } // namespace | |
| 573 } // namespace system | |
| 574 } // namespace mojo | |
| OLD | NEW |