Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Unified Diff: mojo/edk/system/data_pipe_unittest.cc

Issue 2259363002: Mojo EDK: Add tests to exercise races in handle transit (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: mojo/edk/system/data_pipe_unittest.cc
diff --git a/mojo/edk/system/data_pipe_unittest.cc b/mojo/edk/system/data_pipe_unittest.cc
index 526444c6d58095e13cc76115380c2c9cc6b390da..6f8362e69c4a9607626dc7c942a549ebebb8e381 100644
--- a/mojo/edk/system/data_pipe_unittest.cc
+++ b/mojo/edk/system/data_pipe_unittest.cc
@@ -12,6 +12,7 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/platform_channel_pair.h"
#include "mojo/edk/system/test_utils.h"
@@ -20,6 +21,7 @@
#include "mojo/public/c/system/data_pipe.h"
#include "mojo/public/c/system/functions.h"
#include "mojo/public/c/system/message_pipe.h"
+#include "mojo/public/cpp/system/watcher.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
@@ -1898,6 +1900,90 @@ TEST_F(DataPipeTest, CreateInChild) {
END_CHILD()
}
+DEFINE_TEST_CLIENT_TEST_WITH_PIPE(DataPipeStatusChangeInTransitClient,
+ DataPipeTest, parent) {
+ // This test verifies that peer closure is detectable through various
+ // mechanisms when it races with handle transfer.
+
+ MojoHandle handles[6];
+ EXPECT_EQ("o_O", ReadMessageWithHandles(parent, handles, 6));
+ MojoHandle* producers = &handles[0];
+ MojoHandle* consumers = &handles[3];
+
+ // Wait on producer 0 using MojoWait.
+ EXPECT_EQ(MOJO_RESULT_OK,
+ MojoWait(producers[0], MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+ MOJO_DEADLINE_INDEFINITE, nullptr));
+
+ // Wait on consumer 0 using MojoWait.
+ EXPECT_EQ(MOJO_RESULT_OK,
+ MojoWait(consumers[0], MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+ MOJO_DEADLINE_INDEFINITE, nullptr));
+
+ base::MessageLoop message_loop;
+
+ // Wait on producer 1 and consumer 1 using Watchers.
+ {
+ base::RunLoop run_loop;
+ int count = 0;
+ auto callback = base::Bind(
+ [] (base::RunLoop* loop, int* count, MojoResult result) {
+ EXPECT_EQ(MOJO_RESULT_OK, result);
+ if (++*count == 2)
+ loop->Quit();
+ },
+ &run_loop, &count);
+ Watcher producer_watcher, consumer_watcher;
+ producer_watcher.Start(
+ Handle(producers[1]), MOJO_HANDLE_SIGNAL_PEER_CLOSED, callback);
+ consumer_watcher.Start(
+ Handle(consumers[1]), MOJO_HANDLE_SIGNAL_PEER_CLOSED, callback);
+ run_loop.Run();
+ }
+
+ // Wait on producer 2 by polling with MojoWriteData.
+ MojoResult result;
+ do {
+ uint32_t num_bytes = 0;
+ result = MojoWriteData(
+ producers[2], nullptr, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE);
+ } while (result == MOJO_RESULT_OK);
+ EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
+
+ // Wait on consumer 2 by polling with MojoReadData.
+ do {
+ char byte;
+ uint32_t num_bytes = 1;
+ result = MojoReadData(
+ consumers[2], &byte, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
+ } while (result == MOJO_RESULT_SHOULD_WAIT);
+ EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
+
+ for (size_t i = 0; i < 6; ++i)
+ CloseHandle(handles[i]);
+}
+
+TEST_F(DataPipeTest, StatusChangeInTransit) {
+ MojoHandle producers[6];
+ MojoHandle consumers[6];
+ for (size_t i = 0; i < 6; ++i)
+ CreateDataPipe(&producers[i], &consumers[i], 1);
+
+ RUN_CHILD_ON_PIPE(DataPipeStatusChangeInTransitClient, child)
+ MojoHandle handles[] = { producers[0], producers[1], producers[2],
+ consumers[3], consumers[4], consumers[5] };
+
+ // Send 3 producers and 3 consumers, and let their transfer race with their
+ // peers' closure.
+ WriteMessageWithHandles(child, "o_O", handles, 6);
+
+ for (size_t i = 0; i < 3; ++i)
+ CloseHandle(consumers[i]);
+ for (size_t i = 3; i < 6; ++i)
+ CloseHandle(producers[i]);
+ END_CHILD()
+}
+
#endif // !defined(OS_IOS)
} // namespace
« no previous file with comments | « mojo/edk/system/data_pipe_producer_dispatcher.cc ('k') | mojo/edk/system/multiprocess_message_pipe_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698