| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 // TODO(vtl): The POSIX-specific bits have been factored out. Apply this test to | 5 // TODO(vtl): The POSIX-specific bits have been factored out. Apply this test to |
| 6 // non-POSIX once we have a non-POSIX implementation. | 6 // non-POSIX once we have a non-POSIX implementation. |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 | 10 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 test::PostTaskAndWait(io_thread_task_runner(), | 44 test::PostTaskAndWait(io_thread_task_runner(), |
| 45 FROM_HERE, | 45 FROM_HERE, |
| 46 base::Bind(&RemoteMessagePipeTest::TearDownOnIOThread, | 46 base::Bind(&RemoteMessagePipeTest::TearDownOnIOThread, |
| 47 base::Unretained(this))); | 47 base::Unretained(this))); |
| 48 test::TestWithIOThreadBase::TearDown(); | 48 test::TestWithIOThreadBase::TearDown(); |
| 49 } | 49 } |
| 50 | 50 |
| 51 // This connects MP 0, port 1 and MP 1, port 0 (leaving MP 0, port 0 and MP 1, | 51 // This connects MP 0, port 1 and MP 1, port 0 (leaving MP 0, port 0 and MP 1, |
| 52 // port 1 as the user-visible endpoints) to channel 0 and 1, respectively. MP | 52 // port 1 as the user-visible endpoints) to channel 0 and 1, respectively. MP |
| 53 // 0, port 1 and MP 1, port 0 must have |ProxyMessagePipeEndpoint|s. | 53 // 0, port 1 and MP 1, port 0 must have |ProxyMessagePipeEndpoint|s. |
| 54 void ConnectMessagePipes(scoped_refptr<MessagePipe> mp_0, | 54 void ConnectMessagePipes(scoped_refptr<MessagePipe> mp0, |
| 55 scoped_refptr<MessagePipe> mp_1) { | 55 scoped_refptr<MessagePipe> mp1) { |
| 56 test::PostTaskAndWait( | 56 test::PostTaskAndWait( |
| 57 io_thread_task_runner(), | 57 io_thread_task_runner(), |
| 58 FROM_HERE, | 58 FROM_HERE, |
| 59 base::Bind(&RemoteMessagePipeTest::ConnectMessagePipesOnIOThread, | 59 base::Bind(&RemoteMessagePipeTest::ConnectMessagePipesOnIOThread, |
| 60 base::Unretained(this), mp_0, mp_1)); | 60 base::Unretained(this), mp0, mp1)); |
| 61 } | 61 } |
| 62 | 62 |
| 63 // This connects |mp|'s port |channel_index ^ 1| to channel |channel_index|. | 63 // This connects |mp|'s port |channel_index ^ 1| to channel |channel_index|. |
| 64 // It assumes/requires that this is the bootstrap case, i.e., that the | 64 // It assumes/requires that this is the bootstrap case, i.e., that the |
| 65 // endpoint IDs are both/will both be |Channel::kBootstrapEndpointId|. This | 65 // endpoint IDs are both/will both be |Channel::kBootstrapEndpointId|. This |
| 66 // returns *without* waiting for it to finish connecting. | 66 // returns *without* waiting for it to finish connecting. |
| 67 void BootstrapMessagePipeNoWait(unsigned channel_index, | 67 void BootstrapMessagePipeNoWait(unsigned channel_index, |
| 68 scoped_refptr<MessagePipe> mp) { | 68 scoped_refptr<MessagePipe> mp) { |
| 69 io_thread_task_runner()->PostTask( | 69 io_thread_task_runner()->PostTask( |
| 70 FROM_HERE, | 70 FROM_HERE, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 84 void CreateAndInitChannel(unsigned channel_index) { | 84 void CreateAndInitChannel(unsigned channel_index) { |
| 85 CHECK_EQ(base::MessageLoop::current(), io_thread_message_loop()); | 85 CHECK_EQ(base::MessageLoop::current(), io_thread_message_loop()); |
| 86 CHECK(channel_index == 0 || channel_index == 1); | 86 CHECK(channel_index == 0 || channel_index == 1); |
| 87 CHECK(!channels_[channel_index].get()); | 87 CHECK(!channels_[channel_index].get()); |
| 88 | 88 |
| 89 channels_[channel_index] = new Channel(); | 89 channels_[channel_index] = new Channel(); |
| 90 CHECK(channels_[channel_index]->Init( | 90 CHECK(channels_[channel_index]->Init( |
| 91 platform_handles_[channel_index].Pass())); | 91 platform_handles_[channel_index].Pass())); |
| 92 } | 92 } |
| 93 | 93 |
| 94 void ConnectMessagePipesOnIOThread(scoped_refptr<MessagePipe> mp_0, | 94 void ConnectMessagePipesOnIOThread(scoped_refptr<MessagePipe> mp0, |
| 95 scoped_refptr<MessagePipe> mp_1) { | 95 scoped_refptr<MessagePipe> mp1) { |
| 96 CHECK_EQ(base::MessageLoop::current(), io_thread_message_loop()); | 96 CHECK_EQ(base::MessageLoop::current(), io_thread_message_loop()); |
| 97 | 97 |
| 98 if (!channels_[0].get()) | 98 if (!channels_[0].get()) |
| 99 CreateAndInitChannel(0); | 99 CreateAndInitChannel(0); |
| 100 if (!channels_[1].get()) | 100 if (!channels_[1].get()) |
| 101 CreateAndInitChannel(1); | 101 CreateAndInitChannel(1); |
| 102 | 102 |
| 103 MessageInTransit::EndpointId local_id_0 = | 103 MessageInTransit::EndpointId local_id0 = |
| 104 channels_[0]->AttachMessagePipeEndpoint(mp_0, 1); | 104 channels_[0]->AttachMessagePipeEndpoint(mp0, 1); |
| 105 MessageInTransit::EndpointId local_id_1 = | 105 MessageInTransit::EndpointId local_id1 = |
| 106 channels_[1]->AttachMessagePipeEndpoint(mp_1, 0); | 106 channels_[1]->AttachMessagePipeEndpoint(mp1, 0); |
| 107 | 107 |
| 108 channels_[0]->RunMessagePipeEndpoint(local_id_0, local_id_1); | 108 channels_[0]->RunMessagePipeEndpoint(local_id0, local_id1); |
| 109 channels_[1]->RunMessagePipeEndpoint(local_id_1, local_id_0); | 109 channels_[1]->RunMessagePipeEndpoint(local_id1, local_id0); |
| 110 } | 110 } |
| 111 | 111 |
| 112 void BootstrapMessagePipeOnIOThread(unsigned channel_index, | 112 void BootstrapMessagePipeOnIOThread(unsigned channel_index, |
| 113 scoped_refptr<MessagePipe> mp) { | 113 scoped_refptr<MessagePipe> mp) { |
| 114 CHECK_EQ(base::MessageLoop::current(), io_thread_message_loop()); | 114 CHECK_EQ(base::MessageLoop::current(), io_thread_message_loop()); |
| 115 CHECK(channel_index == 0 || channel_index == 1); | 115 CHECK(channel_index == 0 || channel_index == 1); |
| 116 | 116 |
| 117 unsigned port = channel_index ^ 1u; | 117 unsigned port = channel_index ^ 1u; |
| 118 | 118 |
| 119 // Important: If we don't boot | 119 // Important: If we don't boot |
| (...skipping 25 matching lines...) Expand all Loading... |
| 145 const char hello[] = "hello"; | 145 const char hello[] = "hello"; |
| 146 const char world[] = "world!!!1!!!1!"; | 146 const char world[] = "world!!!1!!!1!"; |
| 147 char buffer[100] = { 0 }; | 147 char buffer[100] = { 0 }; |
| 148 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); | 148 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); |
| 149 Waiter waiter; | 149 Waiter waiter; |
| 150 | 150 |
| 151 // Connect message pipes. MP 0, port 1 will be attached to channel 0 and | 151 // Connect message pipes. MP 0, port 1 will be attached to channel 0 and |
| 152 // connected to MP 1, port 0, which will be attached to channel 1. This leaves | 152 // connected to MP 1, port 0, which will be attached to channel 1. This leaves |
| 153 // MP 0, port 0 and MP 1, port 1 as the "user-facing" endpoints. | 153 // MP 0, port 0 and MP 1, port 1 as the "user-facing" endpoints. |
| 154 | 154 |
| 155 scoped_refptr<MessagePipe> mp_0(new MessagePipe( | 155 scoped_refptr<MessagePipe> mp0(new MessagePipe( |
| 156 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), | 156 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), |
| 157 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); | 157 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); |
| 158 scoped_refptr<MessagePipe> mp_1(new MessagePipe( | 158 scoped_refptr<MessagePipe> mp1(new MessagePipe( |
| 159 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()), | 159 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()), |
| 160 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()))); | 160 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()))); |
| 161 ConnectMessagePipes(mp_0, mp_1); | 161 ConnectMessagePipes(mp0, mp1); |
| 162 | 162 |
| 163 // Write in one direction: MP 0, port 0 -> ... -> MP 1, port 1. | 163 // Write in one direction: MP 0, port 0 -> ... -> MP 1, port 1. |
| 164 | 164 |
| 165 // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do | 165 // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do |
| 166 // it later, it might already be readable.) | 166 // it later, it might already be readable.) |
| 167 waiter.Init(); | 167 waiter.Init(); |
| 168 EXPECT_EQ(MOJO_RESULT_OK, | 168 EXPECT_EQ(MOJO_RESULT_OK, |
| 169 mp_1->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 123)); | 169 mp1->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 123)); |
| 170 | 170 |
| 171 // Write to MP 0, port 0. | 171 // Write to MP 0, port 0. |
| 172 EXPECT_EQ(MOJO_RESULT_OK, | 172 EXPECT_EQ(MOJO_RESULT_OK, |
| 173 mp_0->WriteMessage(0, | 173 mp0->WriteMessage(0, |
| 174 hello, sizeof(hello), | 174 hello, sizeof(hello), |
| 175 NULL, | 175 NULL, |
| 176 MOJO_WRITE_MESSAGE_FLAG_NONE)); | 176 MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 177 | 177 |
| 178 // Wait. | 178 // Wait. |
| 179 EXPECT_EQ(123, waiter.Wait(MOJO_DEADLINE_INDEFINITE)); | 179 EXPECT_EQ(123, waiter.Wait(MOJO_DEADLINE_INDEFINITE)); |
| 180 mp_1->RemoveWaiter(1, &waiter); | 180 mp1->RemoveWaiter(1, &waiter); |
| 181 | 181 |
| 182 // Read from MP 1, port 1. | 182 // Read from MP 1, port 1. |
| 183 EXPECT_EQ(MOJO_RESULT_OK, | 183 EXPECT_EQ(MOJO_RESULT_OK, |
| 184 mp_1->ReadMessage(1, | 184 mp1->ReadMessage(1, |
| 185 buffer, &buffer_size, | 185 buffer, &buffer_size, |
| 186 NULL, NULL, | 186 NULL, NULL, |
| 187 MOJO_READ_MESSAGE_FLAG_NONE)); | 187 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 188 EXPECT_EQ(sizeof(hello), static_cast<size_t>(buffer_size)); | 188 EXPECT_EQ(sizeof(hello), static_cast<size_t>(buffer_size)); |
| 189 EXPECT_EQ(0, strcmp(buffer, hello)); | 189 EXPECT_EQ(0, strcmp(buffer, hello)); |
| 190 | 190 |
| 191 // Write in the other direction: MP 1, port 1 -> ... -> MP 0, port 0. | 191 // Write in the other direction: MP 1, port 1 -> ... -> MP 0, port 0. |
| 192 | 192 |
| 193 waiter.Init(); | 193 waiter.Init(); |
| 194 EXPECT_EQ(MOJO_RESULT_OK, | 194 EXPECT_EQ(MOJO_RESULT_OK, |
| 195 mp_0->AddWaiter(0, &waiter, MOJO_WAIT_FLAG_READABLE, 456)); | 195 mp0->AddWaiter(0, &waiter, MOJO_WAIT_FLAG_READABLE, 456)); |
| 196 | 196 |
| 197 EXPECT_EQ(MOJO_RESULT_OK, | 197 EXPECT_EQ(MOJO_RESULT_OK, |
| 198 mp_1->WriteMessage(1, | 198 mp1->WriteMessage(1, |
| 199 world, sizeof(world), | 199 world, sizeof(world), |
| 200 NULL, | 200 NULL, |
| 201 MOJO_WRITE_MESSAGE_FLAG_NONE)); | 201 MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 202 | 202 |
| 203 EXPECT_EQ(456, waiter.Wait(MOJO_DEADLINE_INDEFINITE)); | 203 EXPECT_EQ(456, waiter.Wait(MOJO_DEADLINE_INDEFINITE)); |
| 204 mp_0->RemoveWaiter(0, &waiter); | 204 mp0->RemoveWaiter(0, &waiter); |
| 205 | 205 |
| 206 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | 206 buffer_size = static_cast<uint32_t>(sizeof(buffer)); |
| 207 EXPECT_EQ(MOJO_RESULT_OK, | 207 EXPECT_EQ(MOJO_RESULT_OK, |
| 208 mp_0->ReadMessage(0, | 208 mp0->ReadMessage(0, |
| 209 buffer, &buffer_size, | 209 buffer, &buffer_size, |
| 210 NULL, NULL, | 210 NULL, NULL, |
| 211 MOJO_READ_MESSAGE_FLAG_NONE)); | 211 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 212 EXPECT_EQ(sizeof(world), static_cast<size_t>(buffer_size)); | 212 EXPECT_EQ(sizeof(world), static_cast<size_t>(buffer_size)); |
| 213 EXPECT_EQ(0, strcmp(buffer, world)); | 213 EXPECT_EQ(0, strcmp(buffer, world)); |
| 214 | 214 |
| 215 // Close MP 0, port 0. | 215 // Close MP 0, port 0. |
| 216 mp_0->Close(0); | 216 mp0->Close(0); |
| 217 | 217 |
| 218 // Try to wait for MP 1, port 1 to become readable. This will eventually fail | 218 // Try to wait for MP 1, port 1 to become readable. This will eventually fail |
| 219 // when it realizes that MP 0, port 0 has been closed. (It may also fail | 219 // when it realizes that MP 0, port 0 has been closed. (It may also fail |
| 220 // immediately.) | 220 // immediately.) |
| 221 waiter.Init(); | 221 waiter.Init(); |
| 222 MojoResult result = mp_1->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 789); | 222 MojoResult result = mp1->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 789); |
| 223 if (result == MOJO_RESULT_OK) { | 223 if (result == MOJO_RESULT_OK) { |
| 224 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | 224 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
| 225 waiter.Wait(MOJO_DEADLINE_INDEFINITE)); | 225 waiter.Wait(MOJO_DEADLINE_INDEFINITE)); |
| 226 mp_1->RemoveWaiter(1, &waiter); | 226 mp1->RemoveWaiter(1, &waiter); |
| 227 } else { | 227 } else { |
| 228 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 228 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
| 229 } | 229 } |
| 230 | 230 |
| 231 // And MP 1, port 1. | 231 // And MP 1, port 1. |
| 232 mp_1->Close(1); | 232 mp1->Close(1); |
| 233 } | 233 } |
| 234 | 234 |
| 235 TEST_F(RemoteMessagePipeTest, Multiplex) { | 235 TEST_F(RemoteMessagePipeTest, Multiplex) { |
| 236 const char hello[] = "hello"; | 236 const char hello[] = "hello"; |
| 237 const char world[] = "world!!!1!!!1!"; | 237 const char world[] = "world!!!1!!!1!"; |
| 238 char buffer[100] = { 0 }; | 238 char buffer[100] = { 0 }; |
| 239 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); | 239 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); |
| 240 Waiter waiter; | 240 Waiter waiter; |
| 241 | 241 |
| 242 // Connect message pipes as in the |Basic| test. | 242 // Connect message pipes as in the |Basic| test. |
| 243 | 243 |
| 244 scoped_refptr<MessagePipe> mp_0(new MessagePipe( | 244 scoped_refptr<MessagePipe> mp0(new MessagePipe( |
| 245 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), | 245 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), |
| 246 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); | 246 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); |
| 247 scoped_refptr<MessagePipe> mp_1(new MessagePipe( | 247 scoped_refptr<MessagePipe> mp1(new MessagePipe( |
| 248 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()), | 248 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()), |
| 249 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()))); | 249 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()))); |
| 250 ConnectMessagePipes(mp_0, mp_1); | 250 ConnectMessagePipes(mp0, mp1); |
| 251 | 251 |
| 252 // Now put another message pipe on the channel. | 252 // Now put another message pipe on the channel. |
| 253 | 253 |
| 254 scoped_refptr<MessagePipe> mp_2(new MessagePipe( | 254 scoped_refptr<MessagePipe> mp2(new MessagePipe( |
| 255 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), | 255 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), |
| 256 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); | 256 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); |
| 257 scoped_refptr<MessagePipe> mp_3(new MessagePipe( | 257 scoped_refptr<MessagePipe> mp3(new MessagePipe( |
| 258 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()), | 258 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()), |
| 259 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()))); | 259 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()))); |
| 260 ConnectMessagePipes(mp_2, mp_3); | 260 ConnectMessagePipes(mp2, mp3); |
| 261 | 261 |
| 262 // Write: MP 2, port 0 -> MP 3, port 1. | 262 // Write: MP 2, port 0 -> MP 3, port 1. |
| 263 | 263 |
| 264 waiter.Init(); | 264 waiter.Init(); |
| 265 EXPECT_EQ(MOJO_RESULT_OK, | 265 EXPECT_EQ(MOJO_RESULT_OK, |
| 266 mp_3->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 789)); | 266 mp3->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 789)); |
| 267 | 267 |
| 268 EXPECT_EQ(MOJO_RESULT_OK, | 268 EXPECT_EQ(MOJO_RESULT_OK, |
| 269 mp_2->WriteMessage(0, | 269 mp2->WriteMessage(0, |
| 270 hello, sizeof(hello), | 270 hello, sizeof(hello), |
| 271 NULL, | 271 NULL, |
| 272 MOJO_WRITE_MESSAGE_FLAG_NONE)); | 272 MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 273 | 273 |
| 274 EXPECT_EQ(789, waiter.Wait(MOJO_DEADLINE_INDEFINITE)); | 274 EXPECT_EQ(789, waiter.Wait(MOJO_DEADLINE_INDEFINITE)); |
| 275 mp_3->RemoveWaiter(1, &waiter); | 275 mp3->RemoveWaiter(1, &waiter); |
| 276 | 276 |
| 277 // Make sure there's nothing on MP 0, port 0 or MP 1, port 1 or MP 2, port 0. | 277 // Make sure there's nothing on MP 0, port 0 or MP 1, port 1 or MP 2, port 0. |
| 278 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | 278 buffer_size = static_cast<uint32_t>(sizeof(buffer)); |
| 279 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 279 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
| 280 mp_0->ReadMessage(0, | 280 mp0->ReadMessage(0, |
| 281 buffer, &buffer_size, | 281 buffer, &buffer_size, |
| 282 NULL, NULL, | 282 NULL, NULL, |
| 283 MOJO_READ_MESSAGE_FLAG_NONE)); | 283 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 284 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | 284 buffer_size = static_cast<uint32_t>(sizeof(buffer)); |
| 285 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 285 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
| 286 mp_1->ReadMessage(1, | 286 mp1->ReadMessage(1, |
| 287 buffer, &buffer_size, | 287 buffer, &buffer_size, |
| 288 NULL, NULL, | 288 NULL, NULL, |
| 289 MOJO_READ_MESSAGE_FLAG_NONE)); | 289 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 290 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | 290 buffer_size = static_cast<uint32_t>(sizeof(buffer)); |
| 291 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 291 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
| 292 mp_2->ReadMessage(0, | 292 mp2->ReadMessage(0, |
| 293 buffer, &buffer_size, | 293 buffer, &buffer_size, |
| 294 NULL, NULL, | 294 NULL, NULL, |
| 295 MOJO_READ_MESSAGE_FLAG_NONE)); | 295 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 296 | 296 |
| 297 // Read from MP 3, port 1. | 297 // Read from MP 3, port 1. |
| 298 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | 298 buffer_size = static_cast<uint32_t>(sizeof(buffer)); |
| 299 EXPECT_EQ(MOJO_RESULT_OK, | 299 EXPECT_EQ(MOJO_RESULT_OK, |
| 300 mp_3->ReadMessage(1, | 300 mp3->ReadMessage(1, |
| 301 buffer, &buffer_size, | 301 buffer, &buffer_size, |
| 302 NULL, NULL, | 302 NULL, NULL, |
| 303 MOJO_READ_MESSAGE_FLAG_NONE)); | 303 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 304 EXPECT_EQ(sizeof(hello), static_cast<size_t>(buffer_size)); | 304 EXPECT_EQ(sizeof(hello), static_cast<size_t>(buffer_size)); |
| 305 EXPECT_EQ(0, strcmp(buffer, hello)); | 305 EXPECT_EQ(0, strcmp(buffer, hello)); |
| 306 | 306 |
| 307 // Write: MP 0, port 0 -> MP 1, port 1 again. | 307 // Write: MP 0, port 0 -> MP 1, port 1 again. |
| 308 | 308 |
| 309 waiter.Init(); | 309 waiter.Init(); |
| 310 EXPECT_EQ(MOJO_RESULT_OK, | 310 EXPECT_EQ(MOJO_RESULT_OK, |
| 311 mp_1->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 123)); | 311 mp1->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 123)); |
| 312 | 312 |
| 313 EXPECT_EQ(MOJO_RESULT_OK, | 313 EXPECT_EQ(MOJO_RESULT_OK, |
| 314 mp_0->WriteMessage(0, | 314 mp0->WriteMessage(0, |
| 315 world, sizeof(world), | 315 world, sizeof(world), |
| 316 NULL, | 316 NULL, |
| 317 MOJO_WRITE_MESSAGE_FLAG_NONE)); | 317 MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 318 | 318 |
| 319 EXPECT_EQ(123, waiter.Wait(MOJO_DEADLINE_INDEFINITE)); | 319 EXPECT_EQ(123, waiter.Wait(MOJO_DEADLINE_INDEFINITE)); |
| 320 mp_1->RemoveWaiter(1, &waiter); | 320 mp1->RemoveWaiter(1, &waiter); |
| 321 | 321 |
| 322 // Make sure there's nothing on the other ports. | 322 // Make sure there's nothing on the other ports. |
| 323 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | 323 buffer_size = static_cast<uint32_t>(sizeof(buffer)); |
| 324 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 324 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
| 325 mp_0->ReadMessage(0, | 325 mp0->ReadMessage(0, |
| 326 buffer, &buffer_size, | 326 buffer, &buffer_size, |
| 327 NULL, NULL, | 327 NULL, NULL, |
| 328 MOJO_READ_MESSAGE_FLAG_NONE)); | 328 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 329 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | 329 buffer_size = static_cast<uint32_t>(sizeof(buffer)); |
| 330 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 330 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
| 331 mp_2->ReadMessage(0, | 331 mp2->ReadMessage(0, |
| 332 buffer, &buffer_size, | 332 buffer, &buffer_size, |
| 333 NULL, NULL, | 333 NULL, NULL, |
| 334 MOJO_READ_MESSAGE_FLAG_NONE)); | 334 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 335 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | 335 buffer_size = static_cast<uint32_t>(sizeof(buffer)); |
| 336 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 336 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
| 337 mp_3->ReadMessage(1, | 337 mp3->ReadMessage(1, |
| 338 buffer, &buffer_size, | 338 buffer, &buffer_size, |
| 339 NULL, NULL, | 339 NULL, NULL, |
| 340 MOJO_READ_MESSAGE_FLAG_NONE)); | 340 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 341 | 341 |
| 342 buffer_size = static_cast<uint32_t>(sizeof(buffer)); | 342 buffer_size = static_cast<uint32_t>(sizeof(buffer)); |
| 343 EXPECT_EQ(MOJO_RESULT_OK, | 343 EXPECT_EQ(MOJO_RESULT_OK, |
| 344 mp_1->ReadMessage(1, | 344 mp1->ReadMessage(1, |
| 345 buffer, &buffer_size, | 345 buffer, &buffer_size, |
| 346 NULL, NULL, | 346 NULL, NULL, |
| 347 MOJO_READ_MESSAGE_FLAG_NONE)); | 347 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 348 EXPECT_EQ(sizeof(world), static_cast<size_t>(buffer_size)); | 348 EXPECT_EQ(sizeof(world), static_cast<size_t>(buffer_size)); |
| 349 EXPECT_EQ(0, strcmp(buffer, world)); | 349 EXPECT_EQ(0, strcmp(buffer, world)); |
| 350 } | 350 } |
| 351 | 351 |
| 352 TEST_F(RemoteMessagePipeTest, CloseBeforeConnect) { | 352 TEST_F(RemoteMessagePipeTest, CloseBeforeConnect) { |
| 353 const char hello[] = "hello"; | 353 const char hello[] = "hello"; |
| 354 char buffer[100] = { 0 }; | 354 char buffer[100] = { 0 }; |
| 355 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); | 355 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); |
| 356 Waiter waiter; | 356 Waiter waiter; |
| 357 | 357 |
| 358 // Connect message pipes. MP 0, port 1 will be attached to channel 0 and | 358 // Connect message pipes. MP 0, port 1 will be attached to channel 0 and |
| 359 // connected to MP 1, port 0, which will be attached to channel 1. This leaves | 359 // connected to MP 1, port 0, which will be attached to channel 1. This leaves |
| 360 // MP 0, port 0 and MP 1, port 1 as the "user-facing" endpoints. | 360 // MP 0, port 0 and MP 1, port 1 as the "user-facing" endpoints. |
| 361 | 361 |
| 362 scoped_refptr<MessagePipe> mp_0(new MessagePipe( | 362 scoped_refptr<MessagePipe> mp0(new MessagePipe( |
| 363 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), | 363 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), |
| 364 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); | 364 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); |
| 365 | 365 |
| 366 // Write to MP 0, port 0. | 366 // Write to MP 0, port 0. |
| 367 EXPECT_EQ(MOJO_RESULT_OK, | 367 EXPECT_EQ(MOJO_RESULT_OK, |
| 368 mp_0->WriteMessage(0, | 368 mp0->WriteMessage(0, |
| 369 hello, sizeof(hello), | 369 hello, sizeof(hello), |
| 370 NULL, | 370 NULL, |
| 371 MOJO_WRITE_MESSAGE_FLAG_NONE)); | 371 MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 372 | 372 |
| 373 BootstrapMessagePipeNoWait(0, mp_0); | 373 BootstrapMessagePipeNoWait(0, mp0); |
| 374 | 374 |
| 375 | 375 |
| 376 // Close MP 0, port 0 before channel 1 is even connected. | 376 // Close MP 0, port 0 before channel 1 is even connected. |
| 377 mp_0->Close(0); | 377 mp0->Close(0); |
| 378 | 378 |
| 379 scoped_refptr<MessagePipe> mp_1(new MessagePipe( | 379 scoped_refptr<MessagePipe> mp1(new MessagePipe( |
| 380 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()), | 380 scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()), |
| 381 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()))); | 381 scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()))); |
| 382 | 382 |
| 383 // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do | 383 // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do |
| 384 // it later, it might already be readable.) | 384 // it later, it might already be readable.) |
| 385 waiter.Init(); | 385 waiter.Init(); |
| 386 EXPECT_EQ(MOJO_RESULT_OK, | 386 EXPECT_EQ(MOJO_RESULT_OK, |
| 387 mp_1->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 123)); | 387 mp1->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 123)); |
| 388 | 388 |
| 389 BootstrapMessagePipeNoWait(1, mp_1); | 389 BootstrapMessagePipeNoWait(1, mp1); |
| 390 | 390 |
| 391 // Wait. | 391 // Wait. |
| 392 EXPECT_EQ(123, waiter.Wait(MOJO_DEADLINE_INDEFINITE)); | 392 EXPECT_EQ(123, waiter.Wait(MOJO_DEADLINE_INDEFINITE)); |
| 393 mp_1->RemoveWaiter(1, &waiter); | 393 mp1->RemoveWaiter(1, &waiter); |
| 394 | 394 |
| 395 // Read from MP 1, port 1. | 395 // Read from MP 1, port 1. |
| 396 EXPECT_EQ(MOJO_RESULT_OK, | 396 EXPECT_EQ(MOJO_RESULT_OK, |
| 397 mp_1->ReadMessage(1, | 397 mp1->ReadMessage(1, |
| 398 buffer, &buffer_size, | 398 buffer, &buffer_size, |
| 399 NULL, NULL, | 399 NULL, NULL, |
| 400 MOJO_READ_MESSAGE_FLAG_NONE)); | 400 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 401 EXPECT_EQ(sizeof(hello), static_cast<size_t>(buffer_size)); | 401 EXPECT_EQ(sizeof(hello), static_cast<size_t>(buffer_size)); |
| 402 EXPECT_EQ(0, strcmp(buffer, hello)); | 402 EXPECT_EQ(0, strcmp(buffer, hello)); |
| 403 | 403 |
| 404 // And MP 1, port 1. | 404 // And MP 1, port 1. |
| 405 mp_1->Close(1); | 405 mp1->Close(1); |
| 406 } | 406 } |
| 407 |
| 407 } // namespace | 408 } // namespace |
| 408 } // namespace system | 409 } // namespace system |
| 409 } // namespace mojo | 410 } // namespace mojo |
| OLD | NEW |