core_unittest.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  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. #include "mojo/core/core.h"
  5. #include <stdint.h>
  6. #include <limits>
  7. #include "base/bind.h"
  8. #include "base/threading/platform_thread.h"
  9. #include "build/build_config.h"
  10. #include "mojo/core/core_test_base.h"
  11. #include "mojo/public/cpp/system/wait.h"
  12. #if BUILDFLAG(IS_WIN)
  13. #include "base/win/windows_version.h"
  14. #endif
  15. namespace mojo {
  16. namespace core {
  17. namespace {
  18. const MojoHandleSignalsState kEmptyMojoHandleSignalsState = {0u, 0u};
  19. const MojoHandleSignalsState kFullMojoHandleSignalsState = {~0u, ~0u};
  20. const MojoHandleSignals kAllSignals =
  21. MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE |
  22. MOJO_HANDLE_SIGNAL_PEER_CLOSED | MOJO_HANDLE_SIGNAL_PEER_REMOTE |
  23. MOJO_HANDLE_SIGNAL_QUOTA_EXCEEDED;
  24. using CoreTest = test::CoreTestBase;
  25. TEST_F(CoreTest, GetTimeTicksNow) {
  26. const MojoTimeTicks start = core()->GetTimeTicksNow();
  27. ASSERT_NE(static_cast<MojoTimeTicks>(0), start)
  28. << "GetTimeTicksNow should return nonzero value";
  29. base::PlatformThread::Sleep(base::Milliseconds(15));
  30. const MojoTimeTicks finish = core()->GetTimeTicksNow();
  31. // Allow for some fuzz in sleep.
  32. ASSERT_GE((finish - start), static_cast<MojoTimeTicks>(8000))
  33. << "Sleeping should result in increasing time ticks";
  34. }
  35. TEST_F(CoreTest, Basic) {
  36. MockHandleInfo info;
  37. ASSERT_EQ(0u, info.GetCtorCallCount());
  38. MojoHandle h = CreateMockHandle(&info);
  39. ASSERT_EQ(1u, info.GetCtorCallCount());
  40. ASSERT_NE(h, MOJO_HANDLE_INVALID);
  41. ASSERT_EQ(0u, info.GetWriteMessageCallCount());
  42. MojoMessageHandle message;
  43. ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
  44. ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h, message, nullptr));
  45. ASSERT_EQ(1u, info.GetWriteMessageCallCount());
  46. ASSERT_EQ(0u, info.GetReadMessageCallCount());
  47. ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage(h, nullptr, &message));
  48. ASSERT_EQ(1u, info.GetReadMessageCallCount());
  49. ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage(h, nullptr, &message));
  50. ASSERT_EQ(2u, info.GetReadMessageCallCount());
  51. ASSERT_EQ(0u, info.GetWriteDataCallCount());
  52. ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
  53. core()->WriteData(h, nullptr, nullptr, nullptr));
  54. ASSERT_EQ(1u, info.GetWriteDataCallCount());
  55. ASSERT_EQ(0u, info.GetBeginWriteDataCallCount());
  56. ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
  57. core()->BeginWriteData(h, nullptr, nullptr, nullptr));
  58. ASSERT_EQ(1u, info.GetBeginWriteDataCallCount());
  59. ASSERT_EQ(0u, info.GetEndWriteDataCallCount());
  60. ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndWriteData(h, 0, nullptr));
  61. ASSERT_EQ(1u, info.GetEndWriteDataCallCount());
  62. ASSERT_EQ(0u, info.GetReadDataCallCount());
  63. ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
  64. core()->ReadData(h, nullptr, nullptr, nullptr));
  65. ASSERT_EQ(1u, info.GetReadDataCallCount());
  66. ASSERT_EQ(0u, info.GetBeginReadDataCallCount());
  67. ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
  68. core()->BeginReadData(h, nullptr, nullptr, nullptr));
  69. ASSERT_EQ(1u, info.GetBeginReadDataCallCount());
  70. ASSERT_EQ(0u, info.GetEndReadDataCallCount());
  71. ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndReadData(h, 0, nullptr));
  72. ASSERT_EQ(1u, info.GetEndReadDataCallCount());
  73. ASSERT_EQ(0u, info.GetDtorCallCount());
  74. ASSERT_EQ(0u, info.GetCloseCallCount());
  75. ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
  76. ASSERT_EQ(1u, info.GetCloseCallCount());
  77. ASSERT_EQ(1u, info.GetDtorCallCount());
  78. }
  79. TEST_F(CoreTest, InvalidArguments) {
  80. // |Close()|:
  81. {
  82. ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(MOJO_HANDLE_INVALID));
  83. ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(10));
  84. ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(1000000000));
  85. // Test a double-close.
  86. MockHandleInfo info;
  87. MojoHandle h = CreateMockHandle(&info);
  88. ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
  89. ASSERT_EQ(1u, info.GetCloseCallCount());
  90. ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h));
  91. ASSERT_EQ(1u, info.GetCloseCallCount());
  92. }
  93. // |CreateMessagePipe()|: Nothing to check (apart from things that cause
  94. // death).
  95. // |WriteMessageNew()|:
  96. // Only check arguments checked by |Core|, namely |handle|, |handles|, and
  97. // |num_handles|.
  98. ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
  99. core()->WriteMessage(MOJO_HANDLE_INVALID, 0, nullptr));
  100. // |ReadMessageNew()|:
  101. // Only check arguments checked by |Core|, namely |handle|, |handles|, and
  102. // |num_handles|.
  103. {
  104. ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
  105. core()->ReadMessage(MOJO_HANDLE_INVALID, nullptr, nullptr));
  106. MockHandleInfo info;
  107. MojoHandle h = CreateMockHandle(&info);
  108. ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
  109. core()->ReadMessage(h, nullptr, nullptr));
  110. // Checked by |Core|, shouldn't go through to the dispatcher.
  111. ASSERT_EQ(0u, info.GetReadMessageCallCount());
  112. ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
  113. }
  114. }
  115. TEST_F(CoreTest, MessagePipe) {
  116. MojoHandle h[2];
  117. MojoHandleSignalsState hss[2];
  118. ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessagePipe(nullptr, &h[0], &h[1]));
  119. // Should get two distinct, valid handles.
  120. ASSERT_NE(h[0], MOJO_HANDLE_INVALID);
  121. ASSERT_NE(h[1], MOJO_HANDLE_INVALID);
  122. ASSERT_NE(h[0], h[1]);
  123. // Neither should be readable.
  124. hss[0] = kEmptyMojoHandleSignalsState;
  125. hss[1] = kEmptyMojoHandleSignalsState;
  126. EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(h[0], &hss[0]));
  127. EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(h[1], &hss[1]));
  128. ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
  129. ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
  130. ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals);
  131. ASSERT_EQ(kAllSignals, hss[1].satisfiable_signals);
  132. // Try to read anyway.
  133. MojoMessageHandle message;
  134. ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT,
  135. core()->ReadMessage(h[0], nullptr, &message));
  136. // Write to |h[1]|.
  137. const uintptr_t kTestMessageContext = 123;
  138. ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
  139. ASSERT_EQ(MOJO_RESULT_OK,
  140. core()->SetMessageContext(message, kTestMessageContext, nullptr,
  141. nullptr, nullptr));
  142. ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h[1], message, nullptr));
  143. // Wait for |h[0]| to become readable.
  144. EXPECT_EQ(MOJO_RESULT_OK, mojo::Wait(mojo::Handle(h[0]),
  145. MOJO_HANDLE_SIGNAL_READABLE, &hss[0]));
  146. // Read from |h[0]|.
  147. ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage(h[0], nullptr, &message));
  148. uintptr_t context;
  149. ASSERT_EQ(MOJO_RESULT_OK,
  150. core()->GetMessageContext(message, nullptr, &context));
  151. ASSERT_EQ(MOJO_RESULT_OK,
  152. core()->SetMessageContext(message, 0, nullptr, nullptr, nullptr));
  153. ASSERT_EQ(kTestMessageContext, context);
  154. ASSERT_EQ(MOJO_RESULT_OK, core()->DestroyMessage(message));
  155. // |h[0]| should no longer be readable.
  156. hss[0] = kEmptyMojoHandleSignalsState;
  157. EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(h[0], &hss[0]));
  158. ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
  159. ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
  160. // Write to |h[0]|.
  161. ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
  162. ASSERT_EQ(MOJO_RESULT_OK,
  163. core()->SetMessageContext(message, kTestMessageContext, nullptr,
  164. nullptr, nullptr));
  165. ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h[0], message, nullptr));
  166. // Close |h[0]|.
  167. ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h[0]));
  168. // Wait for |h[1]| to learn about the other end's closure.
  169. EXPECT_EQ(
  170. MOJO_RESULT_OK,
  171. mojo::Wait(mojo::Handle(h[1]), MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss[1]));
  172. // Check that |h[1]| is no longer writable (and will never be).
  173. EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
  174. hss[1].satisfied_signals);
  175. EXPECT_FALSE(hss[1].satisfiable_signals & MOJO_HANDLE_SIGNAL_WRITABLE);
  176. // Check that |h[1]| is still readable (for the moment).
  177. EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
  178. hss[1].satisfied_signals);
  179. EXPECT_TRUE(hss[1].satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
  180. // Discard a message from |h[1]|.
  181. ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage(h[1], nullptr, &message));
  182. ASSERT_EQ(MOJO_RESULT_OK, core()->DestroyMessage(message));
  183. // |h[1]| is no longer readable (and will never be).
  184. hss[1] = kFullMojoHandleSignalsState;
  185. EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(h[1], &hss[1]));
  186. EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[1].satisfied_signals);
  187. EXPECT_FALSE(hss[1].satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
  188. // Try writing to |h[1]|.
  189. ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
  190. ASSERT_EQ(MOJO_RESULT_OK,
  191. core()->SetMessageContext(message, kTestMessageContext, nullptr,
  192. nullptr, nullptr));
  193. ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
  194. core()->WriteMessage(h[1], message, nullptr));
  195. ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h[1]));
  196. }
  197. // Tests passing a message pipe handle.
  198. TEST_F(CoreTest, MessagePipeBasicLocalHandlePassing1) {
  199. MojoHandleSignalsState hss;
  200. MojoHandle h_passing[2];
  201. ASSERT_EQ(MOJO_RESULT_OK,
  202. core()->CreateMessagePipe(nullptr, &h_passing[0], &h_passing[1]));
  203. // Make sure that |h_passing[]| work properly.
  204. const uintptr_t kTestMessageContext = 42;
  205. MojoMessageHandle message;
  206. ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
  207. ASSERT_EQ(MOJO_RESULT_OK,
  208. core()->SetMessageContext(message, kTestMessageContext, nullptr,
  209. nullptr, nullptr));
  210. ASSERT_EQ(MOJO_RESULT_OK,
  211. core()->WriteMessage(h_passing[0], message, nullptr));
  212. hss = kEmptyMojoHandleSignalsState;
  213. EXPECT_EQ(MOJO_RESULT_OK, mojo::Wait(mojo::Handle(h_passing[1]),
  214. MOJO_HANDLE_SIGNAL_READABLE, &hss));
  215. ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
  216. hss.satisfied_signals);
  217. ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
  218. MojoMessageHandle message_handle;
  219. ASSERT_EQ(MOJO_RESULT_OK,
  220. core()->ReadMessage(h_passing[1], nullptr, &message_handle));
  221. uintptr_t context;
  222. ASSERT_EQ(MOJO_RESULT_OK,
  223. core()->GetMessageContext(message_handle, nullptr, &context));
  224. ASSERT_EQ(MOJO_RESULT_OK,
  225. core()->SetMessageContext(message, 0, nullptr, nullptr, nullptr));
  226. ASSERT_EQ(kTestMessageContext, context);
  227. ASSERT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message_handle));
  228. ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0]));
  229. ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1]));
  230. }
  231. TEST_F(CoreTest, DataPipe) {
  232. MojoHandle ph, ch; // p is for producer and c is for consumer.
  233. MojoHandleSignalsState hss;
  234. ASSERT_EQ(MOJO_RESULT_OK, core()->CreateDataPipe(nullptr, &ph, &ch));
  235. // Should get two distinct, valid handles.
  236. ASSERT_NE(ph, MOJO_HANDLE_INVALID);
  237. ASSERT_NE(ch, MOJO_HANDLE_INVALID);
  238. ASSERT_NE(ph, ch);
  239. // Producer should be never-readable, but already writable.
  240. hss = kEmptyMojoHandleSignalsState;
  241. EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ph, &hss));
  242. ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
  243. ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
  244. MOJO_HANDLE_SIGNAL_PEER_REMOTE,
  245. hss.satisfiable_signals);
  246. // Consumer should be never-writable, and not yet readable.
  247. hss = kFullMojoHandleSignalsState;
  248. EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ch, &hss));
  249. EXPECT_EQ(0u, hss.satisfied_signals);
  250. EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
  251. MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE |
  252. MOJO_HANDLE_SIGNAL_PEER_REMOTE,
  253. hss.satisfiable_signals);
  254. // Write.
  255. signed char elements[2] = {'A', 'B'};
  256. uint32_t num_bytes = 2u;
  257. ASSERT_EQ(MOJO_RESULT_OK,
  258. core()->WriteData(ph, elements, &num_bytes, nullptr));
  259. ASSERT_EQ(2u, num_bytes);
  260. // Wait for the data to arrive to the consumer.
  261. EXPECT_EQ(MOJO_RESULT_OK,
  262. mojo::Wait(mojo::Handle(ch), MOJO_HANDLE_SIGNAL_READABLE, &hss));
  263. // Consumer should now be readable.
  264. hss = kEmptyMojoHandleSignalsState;
  265. EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ch, &hss));
  266. EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
  267. hss.satisfied_signals);
  268. EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
  269. MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE |
  270. MOJO_HANDLE_SIGNAL_PEER_REMOTE,
  271. hss.satisfiable_signals);
  272. // Peek one character.
  273. elements[0] = -1;
  274. elements[1] = -1;
  275. num_bytes = 1u;
  276. MojoReadDataOptions read_options;
  277. read_options.struct_size = sizeof(read_options);
  278. read_options.flags = MOJO_READ_DATA_FLAG_NONE | MOJO_READ_DATA_FLAG_PEEK;
  279. ASSERT_EQ(MOJO_RESULT_OK,
  280. core()->ReadData(ch, &read_options, elements, &num_bytes));
  281. ASSERT_EQ('A', elements[0]);
  282. ASSERT_EQ(-1, elements[1]);
  283. // Read one character.
  284. elements[0] = -1;
  285. elements[1] = -1;
  286. num_bytes = 1u;
  287. read_options.flags = MOJO_READ_DATA_FLAG_NONE;
  288. ASSERT_EQ(MOJO_RESULT_OK,
  289. core()->ReadData(ch, &read_options, elements, &num_bytes));
  290. ASSERT_EQ('A', elements[0]);
  291. ASSERT_EQ(-1, elements[1]);
  292. // Two-phase write.
  293. void* write_ptr = nullptr;
  294. num_bytes = 0u;
  295. ASSERT_EQ(MOJO_RESULT_OK,
  296. core()->BeginWriteData(ph, nullptr, &write_ptr, &num_bytes));
  297. // We count on the default options providing a decent buffer size.
  298. ASSERT_GE(num_bytes, 3u);
  299. // Trying to do a normal write during a two-phase write should fail.
  300. elements[0] = 'X';
  301. num_bytes = 1u;
  302. ASSERT_EQ(MOJO_RESULT_BUSY,
  303. core()->WriteData(ph, elements, &num_bytes, nullptr));
  304. // Actually write the data, and complete it now.
  305. static_cast<char*>(write_ptr)[0] = 'C';
  306. static_cast<char*>(write_ptr)[1] = 'D';
  307. static_cast<char*>(write_ptr)[2] = 'E';
  308. ASSERT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 3u, nullptr));
  309. // Wait for the data to arrive to the consumer.
  310. ASSERT_EQ(MOJO_RESULT_OK,
  311. mojo::Wait(mojo::Handle(ch), MOJO_HANDLE_SIGNAL_READABLE, &hss));
  312. // Query how much data we have.
  313. num_bytes = 0;
  314. read_options.flags = MOJO_READ_DATA_FLAG_QUERY;
  315. ASSERT_EQ(MOJO_RESULT_OK,
  316. core()->ReadData(ch, &read_options, nullptr, &num_bytes));
  317. ASSERT_GE(num_bytes, 1u);
  318. // Try to query with peek. Should fail.
  319. num_bytes = 0;
  320. read_options.flags = MOJO_READ_DATA_FLAG_QUERY | MOJO_READ_DATA_FLAG_PEEK;
  321. ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
  322. core()->ReadData(ch, &read_options, nullptr, &num_bytes));
  323. ASSERT_EQ(0u, num_bytes);
  324. // Try to discard ten characters, in all-or-none mode. Should fail.
  325. num_bytes = 10;
  326. read_options.flags =
  327. MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE;
  328. ASSERT_EQ(MOJO_RESULT_OUT_OF_RANGE,
  329. core()->ReadData(ch, &read_options, nullptr, &num_bytes));
  330. // Try to discard two characters, in peek mode. Should fail.
  331. num_bytes = 2;
  332. read_options.flags = MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_PEEK;
  333. ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
  334. core()->ReadData(ch, &read_options, nullptr, &num_bytes));
  335. // Discard a character.
  336. num_bytes = 1;
  337. read_options.flags =
  338. MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE;
  339. ASSERT_EQ(MOJO_RESULT_OK,
  340. core()->ReadData(ch, &read_options, nullptr, &num_bytes));
  341. // Ensure the 3 bytes were read.
  342. ASSERT_EQ(MOJO_RESULT_OK,
  343. mojo::Wait(mojo::Handle(ch), MOJO_HANDLE_SIGNAL_READABLE, &hss));
  344. // Read the remaining three characters, in two-phase mode.
  345. const void* read_ptr = nullptr;
  346. num_bytes = 3;
  347. ASSERT_EQ(MOJO_RESULT_OK,
  348. core()->BeginReadData(ch, nullptr, &read_ptr, &num_bytes));
  349. // Note: Count on still being able to do the contiguous read here.
  350. ASSERT_EQ(3u, num_bytes);
  351. // Discarding right now should fail.
  352. num_bytes = 1;
  353. read_options.flags = MOJO_READ_DATA_FLAG_DISCARD;
  354. ASSERT_EQ(MOJO_RESULT_BUSY,
  355. core()->ReadData(ch, &read_options, nullptr, &num_bytes));
  356. // Actually check our data and end the two-phase read.
  357. ASSERT_EQ('C', static_cast<const char*>(read_ptr)[0]);
  358. ASSERT_EQ('D', static_cast<const char*>(read_ptr)[1]);
  359. ASSERT_EQ('E', static_cast<const char*>(read_ptr)[2]);
  360. ASSERT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 3u, nullptr));
  361. // Consumer should now be no longer readable.
  362. hss = kFullMojoHandleSignalsState;
  363. EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ch, &hss));
  364. EXPECT_EQ(0u, hss.satisfied_signals);
  365. EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
  366. MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE |
  367. MOJO_HANDLE_SIGNAL_PEER_REMOTE,
  368. hss.satisfiable_signals);
  369. // TODO(vtl): More.
  370. // Close the producer.
  371. ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ph));
  372. // Wait for this to get to the consumer.
  373. EXPECT_EQ(MOJO_RESULT_OK,
  374. mojo::Wait(mojo::Handle(ch), MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss));
  375. // The consumer should now be never-readable.
  376. hss = kFullMojoHandleSignalsState;
  377. EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ch, &hss));
  378. ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
  379. ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
  380. ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ch));
  381. }
  382. } // namespace
  383. } // namespace core
  384. } // namespace mojo