Mojo EDK: Introduce MojoQueryHandleSignalsState API
The only reliable way to inquire about handle signals now
is to MojoWait (for e.g. 0 deadline). As a precursor to
removing the wait APIs in favor of watchers, we need to
retain the ability to efficiently query a handle's signals
state.
Rather than trying to retrofit the watcher APIs to support
this use case in similar fashion to the wait APIs, this adds
an API explicitly for the purpose of querying signals state.
Adds a corresponding method to the C++ mojo::Handle
and moves the EDK's internal HandleSignalsState helper class
to mojo/public/cpp/system, adding some convenient accessors.
Also introduces the API to the JS and Java libraries, and
replaces any 0-deadline waits in those languages with usage of
this new API.
Because waitMany is not used in these languages (except for
tests which test waitMany...) it has been removed. wait() is
unused in Java after this change, so it has also been removed.
Finally, this moves several tests away from calling MojoWait
directly, instead using a simplified Watcher-based wait
implementation in MojoTestBase.
BUG=700171
TBR=jam@chromium.org
Review-Url: https://codereview.chromium.org/2741033003
Cr-Original-Commit-Position: refs/heads/master@{#457315}
Committed: https://chromium.googlesource.com/chromium/src/+/853496a78ae997c2d8b80f3cd8fabf9423fb3361
Review-Url: https://codereview.chromium.org/2741033003
Cr-Commit-Position: refs/heads/master@{#457378}
CrOS-Libchrome-Original-Commit: c7949549ac0c42252c8b3f2c08d4cb34b65dc869
diff --git a/mojo/android/javatests/src/org/chromium/mojo/HandleMock.java b/mojo/android/javatests/src/org/chromium/mojo/HandleMock.java
index 6783c09..1f8de94 100644
--- a/mojo/android/javatests/src/org/chromium/mojo/HandleMock.java
+++ b/mojo/android/javatests/src/org/chromium/mojo/HandleMock.java
@@ -5,7 +5,7 @@
package org.chromium.mojo;
import org.chromium.mojo.system.Core;
-import org.chromium.mojo.system.Core.WaitResult;
+import org.chromium.mojo.system.Core.HandleSignalsState;
import org.chromium.mojo.system.DataPipe;
import org.chromium.mojo.system.DataPipe.ConsumerHandle;
import org.chromium.mojo.system.DataPipe.ProducerHandle;
@@ -35,14 +35,11 @@
}
/**
- * @see Handle#wait(Core.HandleSignals, long)
+ * @see Handle#querySignalsState()
*/
@Override
- public WaitResult wait(Core.HandleSignals signals, long deadline) {
- // Do nothing.
- WaitResult result = new WaitResult();
- result.setMojoResult(MojoResult.OK);
- return result;
+ public HandleSignalsState querySignalsState() {
+ return null;
}
/**
diff --git a/mojo/android/javatests/src/org/chromium/mojo/bindings/RouterTest.java b/mojo/android/javatests/src/org/chromium/mojo/bindings/RouterTest.java
index 5affb8f..6aa1726 100644
--- a/mojo/android/javatests/src/org/chromium/mojo/bindings/RouterTest.java
+++ b/mojo/android/javatests/src/org/chromium/mojo/bindings/RouterTest.java
@@ -12,7 +12,6 @@
import org.chromium.mojo.bindings.BindingsTestUtils.RecordingMessageReceiverWithResponder;
import org.chromium.mojo.system.Core;
import org.chromium.mojo.system.Core.HandleSignals;
-import org.chromium.mojo.system.Core.WaitResult;
import org.chromium.mojo.system.Handle;
import org.chromium.mojo.system.MessagePipeHandle;
import org.chromium.mojo.system.MojoResult;
@@ -227,8 +226,6 @@
// Confirm that the pipe was closed on the Router side.
HandleSignals closedFlag = HandleSignals.none().setPeerClosed(true);
- WaitResult result = mHandle.wait(closedFlag, 0);
- assertEquals(MojoResult.OK, result.getMojoResult());
- assertEquals(closedFlag, result.getHandleSignalsState().getSatisfiedSignals());
+ assertEquals(closedFlag, mHandle.querySignalsState().getSatisfiedSignals());
}
}
diff --git a/mojo/android/javatests/src/org/chromium/mojo/system/impl/CoreImplTest.java b/mojo/android/javatests/src/org/chromium/mojo/system/impl/CoreImplTest.java
index 77a9bda..5120198 100644
--- a/mojo/android/javatests/src/org/chromium/mojo/system/impl/CoreImplTest.java
+++ b/mojo/android/javatests/src/org/chromium/mojo/system/impl/CoreImplTest.java
@@ -9,9 +9,6 @@
import org.chromium.mojo.MojoTestCase;
import org.chromium.mojo.system.Core;
import org.chromium.mojo.system.Core.HandleSignals;
-import org.chromium.mojo.system.Core.HandleSignalsState;
-import org.chromium.mojo.system.Core.WaitManyResult;
-import org.chromium.mojo.system.Core.WaitResult;
import org.chromium.mojo.system.DataPipe;
import org.chromium.mojo.system.Handle;
import org.chromium.mojo.system.InvalidHandle;
@@ -30,7 +27,6 @@
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
/**
* Testing the core API.
@@ -76,22 +72,6 @@
mHandlesToClose.add(handles.second);
}
- /**
- * Runnable that will close the given handle.
- */
- private static class CloseHandle implements Runnable {
- private Handle mHandle;
-
- CloseHandle(Handle handle) {
- mHandle = handle;
- }
-
- @Override
- public void run() {
- mHandle.close();
- }
- }
-
private static void checkSendingMessage(MessagePipeHandle in, MessagePipeHandle out) {
Random random = new Random();
@@ -184,46 +164,6 @@
}
/**
- * Testing {@link Core#waitMany(List, long)}.
- */
- @SmallTest
- public void testWaitMany() {
- Core core = CoreImpl.getInstance();
- Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
- addHandlePairToClose(handles);
-
- // Test waiting on handles of a newly created message pipe - each should be writable, but
- // not readable.
- List<Pair<Handle, Core.HandleSignals>> handlesToWaitOn =
- new ArrayList<Pair<Handle, Core.HandleSignals>>();
- handlesToWaitOn.add(
- new Pair<Handle, Core.HandleSignals>(handles.second, Core.HandleSignals.READABLE));
- handlesToWaitOn.add(
- new Pair<Handle, Core.HandleSignals>(handles.first, Core.HandleSignals.WRITABLE));
- WaitManyResult result = core.waitMany(handlesToWaitOn, 0);
- assertEquals(MojoResult.OK, result.getMojoResult());
- assertEquals(1, result.getHandleIndex());
- for (HandleSignalsState state : result.getSignalStates()) {
- assertEquals(HandleSignals.WRITABLE, state.getSatisfiedSignals());
- assertEquals(ALL_SIGNALS, state.getSatisfiableSignals());
- }
-
- // Same test, but swap the handles around.
- handlesToWaitOn.clear();
- handlesToWaitOn.add(
- new Pair<Handle, Core.HandleSignals>(handles.first, Core.HandleSignals.WRITABLE));
- handlesToWaitOn.add(
- new Pair<Handle, Core.HandleSignals>(handles.second, Core.HandleSignals.READABLE));
- result = core.waitMany(handlesToWaitOn, 0);
- assertEquals(MojoResult.OK, result.getMojoResult());
- assertEquals(0, result.getHandleIndex());
- for (HandleSignalsState state : result.getSignalStates()) {
- assertEquals(HandleSignals.WRITABLE, state.getSatisfiedSignals());
- assertEquals(ALL_SIGNALS, state.getSatisfiableSignals());
- }
- }
-
- /**
* Testing that Core can be retrieved from a handle.
*/
@SmallTest
@@ -274,53 +214,14 @@
Core core = CoreImpl.getInstance();
Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe(null);
addHandlePairToClose(handles);
- // Test waiting on handles of a newly created message pipe.
- WaitResult waitResult = handles.first.wait(
- Core.HandleSignals.none().setReadable(true).setWritable(true), 0);
- assertEquals(MojoResult.OK, waitResult.getMojoResult());
- assertEquals(
- HandleSignals.WRITABLE, waitResult.getHandleSignalsState().getSatisfiedSignals());
- assertEquals(ALL_SIGNALS, waitResult.getHandleSignalsState().getSatisfiableSignals());
-
- waitResult = handles.first.wait(Core.HandleSignals.WRITABLE, 0);
- assertEquals(MojoResult.OK, waitResult.getMojoResult());
- assertEquals(
- HandleSignals.WRITABLE, waitResult.getHandleSignalsState().getSatisfiedSignals());
- assertEquals(ALL_SIGNALS, waitResult.getHandleSignalsState().getSatisfiableSignals());
-
- waitResult = handles.first.wait(Core.HandleSignals.READABLE, 0);
- assertEquals(MojoResult.DEADLINE_EXCEEDED, waitResult.getMojoResult());
- assertEquals(
- HandleSignals.WRITABLE, waitResult.getHandleSignalsState().getSatisfiedSignals());
- assertEquals(ALL_SIGNALS, waitResult.getHandleSignalsState().getSatisfiableSignals());
// Testing read on an empty pipe.
ResultAnd<MessagePipeHandle.ReadMessageResult> readResult =
handles.first.readMessage(null, 0, MessagePipeHandle.ReadFlags.NONE);
assertEquals(MojoResult.SHOULD_WAIT, readResult.getMojoResult());
- // Closing a pipe while waiting.
- WORKER.schedule(new CloseHandle(handles.first), 10, TimeUnit.MILLISECONDS);
- waitResult = handles.first.wait(Core.HandleSignals.READABLE, 1000000L);
- assertEquals(MojoResult.CANCELLED, waitResult.getMojoResult());
- assertEquals(
- HandleSignals.none(), waitResult.getHandleSignalsState().getSatisfiedSignals());
- assertEquals(
- HandleSignals.none(), waitResult.getHandleSignalsState().getSatisfiableSignals());
-
- handles = core.createMessagePipe(null);
- addHandlePairToClose(handles);
-
- // Closing the other pipe while waiting.
- WORKER.schedule(new CloseHandle(handles.first), 10, TimeUnit.MILLISECONDS);
- waitResult = handles.second.wait(Core.HandleSignals.READABLE, 1000000L);
- assertEquals(MojoResult.FAILED_PRECONDITION, waitResult.getMojoResult());
-
- // Waiting on a closed pipe.
- waitResult = handles.second.wait(Core.HandleSignals.READABLE, 0);
- assertEquals(MojoResult.FAILED_PRECONDITION, waitResult.getMojoResult());
- waitResult = handles.second.wait(Core.HandleSignals.WRITABLE, 0);
- assertEquals(MojoResult.FAILED_PRECONDITION, waitResult.getMojoResult());
+ handles.first.close();
+ handles.second.close();
}
/**
@@ -540,29 +441,6 @@
Core core = CoreImpl.getInstance();
Handle handle = InvalidHandle.INSTANCE;
- // Checking wait.
- boolean exception = false;
- try {
- core.wait(handle, Core.HandleSignals.WRITABLE, 0);
- } catch (MojoException e) {
- assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult());
- exception = true;
- }
- assertTrue(exception);
-
- // Checking waitMany.
- exception = false;
- try {
- List<Pair<Handle, Core.HandleSignals>> handles =
- new ArrayList<Pair<Handle, Core.HandleSignals>>();
- handles.add(Pair.create(handle, Core.HandleSignals.WRITABLE));
- core.waitMany(handles, 0);
- } catch (MojoException e) {
- assertEquals(MojoResult.INVALID_ARGUMENT, e.getMojoResult());
- exception = true;
- }
- assertTrue(exception);
-
// Checking sending an invalid handle.
// Until the behavior is changed on the C++ side, handle gracefully 2 different use case:
// - Receive a INVALID_ARGUMENT exception
diff --git a/mojo/android/system/core_impl.cc b/mojo/android/system/core_impl.cc
index 5cbd754..e53ed75 100644
--- a/mojo/android/system/core_impl.cc
+++ b/mojo/android/system/core_impl.cc
@@ -26,41 +26,6 @@
return MojoGetTimeTicksNow();
}
-static jint WaitMany(JNIEnv* env,
- const JavaParamRef<jobject>& jcaller,
- const JavaParamRef<jobject>& buffer,
- jlong deadline) {
- // |buffer| contains, in this order
- // input: The array of N handles (MojoHandle, 4 bytes each)
- // input: The array of N signals (MojoHandleSignals, 4 bytes each)
- // space for output: The array of N handle states (MojoHandleSignalsState, 8
- // bytes each)
- // space for output: The result index (uint32_t, 4 bytes)
- uint8_t* buffer_start =
- static_cast<uint8_t*>(env->GetDirectBufferAddress(buffer));
- DCHECK(buffer_start);
- DCHECK_EQ(reinterpret_cast<uintptr_t>(buffer_start) % 8, 0u);
- // Each handle of the input array contributes 4 (MojoHandle) + 4
- // (MojoHandleSignals) + 8 (MojoHandleSignalsState) = 16 bytes to the size of
- // the buffer.
- const size_t size_per_handle = 16;
- const size_t buffer_size = env->GetDirectBufferCapacity(buffer);
- DCHECK_EQ((buffer_size - 4) % size_per_handle, 0u);
-
- const size_t nb_handles = (buffer_size - 4) / size_per_handle;
- const MojoHandle* handle_start =
- reinterpret_cast<const MojoHandle*>(buffer_start);
- const MojoHandleSignals* signals_start =
- reinterpret_cast<const MojoHandleSignals*>(buffer_start + 4 * nb_handles);
- MojoHandleSignalsState* states_start =
- reinterpret_cast<MojoHandleSignalsState*>(buffer_start + 8 * nb_handles);
- uint32_t* result_index =
- reinterpret_cast<uint32_t*>(buffer_start + 16 * nb_handles);
- *result_index = static_cast<uint32_t>(-1);
- return MojoWaitMany(handle_start, signals_start, nb_handles, deadline,
- result_index, states_start);
-}
-
static ScopedJavaLocalRef<jobject> CreateMessagePipe(
JNIEnv* env,
const JavaParamRef<jobject>& jcaller,
@@ -127,21 +92,16 @@
return MojoClose(mojo_handle);
}
-static jint Wait(JNIEnv* env,
- const JavaParamRef<jobject>& jcaller,
- const JavaParamRef<jobject>& buffer,
- jint mojo_handle,
- jint signals,
- jlong deadline) {
- // Buffer contains space for the MojoHandleSignalsState
- void* buffer_start = env->GetDirectBufferAddress(buffer);
- DCHECK(buffer_start);
- DCHECK_EQ(reinterpret_cast<const uintptr_t>(buffer_start) % 8, 0u);
- DCHECK_EQ(sizeof(struct MojoHandleSignalsState),
+static jint QueryHandleSignalsState(JNIEnv* env,
+ const JavaParamRef<jobject>& jcaller,
+ jint mojo_handle,
+ const JavaParamRef<jobject>& buffer) {
+ MojoHandleSignalsState* signals_state =
+ static_cast<MojoHandleSignalsState*>(env->GetDirectBufferAddress(buffer));
+ DCHECK(signals_state);
+ DCHECK_EQ(sizeof(MojoHandleSignalsState),
static_cast<size_t>(env->GetDirectBufferCapacity(buffer)));
- struct MojoHandleSignalsState* signals_state =
- static_cast<struct MojoHandleSignalsState*>(buffer_start);
- return MojoWait(mojo_handle, signals, deadline, signals_state);
+ return MojoQueryHandleSignalsState(mojo_handle, signals_state);
}
static jint WriteMessage(JNIEnv* env,
diff --git a/mojo/android/system/src/org/chromium/mojo/system/impl/CoreImpl.java b/mojo/android/system/src/org/chromium/mojo/system/impl/CoreImpl.java
index 8330586..173f801 100644
--- a/mojo/android/system/src/org/chromium/mojo/system/impl/CoreImpl.java
+++ b/mojo/android/system/src/org/chromium/mojo/system/impl/CoreImpl.java
@@ -8,6 +8,7 @@
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import org.chromium.mojo.system.Core;
+import org.chromium.mojo.system.Core.HandleSignalsState;
import org.chromium.mojo.system.DataPipe;
import org.chromium.mojo.system.DataPipe.ConsumerHandle;
import org.chromium.mojo.system.DataPipe.ProducerHandle;
@@ -27,7 +28,6 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
/**
@@ -91,61 +91,6 @@
}
/**
- * @see Core#waitMany(List, long)
- */
- @Override
- public WaitManyResult waitMany(List<Pair<Handle, HandleSignals>> handles, long deadline) {
- // Allocate a direct buffer to allow native code not to reach back to java. The buffer
- // layout will be:
- // input: The array of handles (int, 4 bytes each)
- // input: The array of signals (int, 4 bytes each)
- // space for output: The array of handle states (2 ints, 8 bytes each)
- // Space for output: The result index (int, 4 bytes)
- // The handles and signals will be filled before calling the native method. When the native
- // method returns, the handle states and the index will have been set.
- ByteBuffer buffer = allocateDirectBuffer(handles.size() * 16 + 4);
- int index = 0;
- for (Pair<Handle, HandleSignals> handle : handles) {
- buffer.putInt(HANDLE_SIZE * index, getMojoHandle(handle.first));
- buffer.putInt(
- HANDLE_SIZE * handles.size() + FLAG_SIZE * index, handle.second.getFlags());
- index++;
- }
- int code = nativeWaitMany(buffer, deadline);
- WaitManyResult result = new WaitManyResult();
- result.setMojoResult(filterMojoResultForWait(code));
- result.setHandleIndex(buffer.getInt(handles.size() * 16));
- if (result.getMojoResult() != MojoResult.INVALID_ARGUMENT
- && result.getMojoResult() != MojoResult.RESOURCE_EXHAUSTED) {
- HandleSignalsState[] states = new HandleSignalsState[handles.size()];
- for (int i = 0; i < handles.size(); ++i) {
- states[i] = new HandleSignalsState(
- new HandleSignals(buffer.getInt(8 * (handles.size() + i))),
- new HandleSignals(buffer.getInt(8 * (handles.size() + i) + 4)));
- }
- result.setSignalStates(Arrays.asList(states));
- }
- return result;
- }
-
- /**
- * @see Core#wait(Handle, HandleSignals, long)
- */
- @Override
- public WaitResult wait(Handle handle, HandleSignals signals, long deadline) {
- // Allocate a direct buffer to allow native code not to reach back to java. Buffer will
- // contain spaces to write the handle state.
- ByteBuffer buffer = allocateDirectBuffer(8);
- WaitResult result = new WaitResult();
- result.setMojoResult(filterMojoResultForWait(
- nativeWait(buffer, getMojoHandle(handle), signals.getFlags(), deadline)));
- HandleSignalsState signalsState = new HandleSignalsState(
- new HandleSignals(buffer.getInt(0)), new HandleSignals(buffer.getInt(4)));
- result.setHandleSignalsState(signalsState);
- return result;
- }
-
- /**
* @see Core#createMessagePipe(MessagePipeHandle.CreateOptions)
*/
@Override
@@ -262,6 +207,14 @@
}
}
+ HandleSignalsState queryHandleSignalsState(int mojoHandle) {
+ ByteBuffer buffer = allocateDirectBuffer(8);
+ int result = nativeQueryHandleSignalsState(mojoHandle, buffer);
+ if (result != MojoResult.OK) throw new MojoException(result);
+ return new HandleSignalsState(
+ new HandleSignals(buffer.getInt(0)), new HandleSignals(buffer.getInt(4)));
+ }
+
/**
* @see MessagePipeHandle#writeMessage(ByteBuffer, List, MessagePipeHandle.WriteFlags)
*/
@@ -525,8 +478,6 @@
private native long nativeGetTimeTicksNow();
- private native int nativeWaitMany(ByteBuffer buffer, long deadline);
-
private native ResultAnd<IntegerPair> nativeCreateMessagePipe(ByteBuffer optionsBuffer);
private native ResultAnd<IntegerPair> nativeCreateDataPipe(ByteBuffer optionsBuffer);
@@ -536,7 +487,7 @@
private native int nativeClose(int mojoHandle);
- private native int nativeWait(ByteBuffer buffer, int mojoHandle, int signals, long deadline);
+ private native int nativeQueryHandleSignalsState(int mojoHandle, ByteBuffer signalsStateBuffer);
private native int nativeWriteMessage(
int mojoHandle, ByteBuffer bytes, int numBytes, ByteBuffer handlesBuffer, int flags);
diff --git a/mojo/android/system/src/org/chromium/mojo/system/impl/HandleBase.java b/mojo/android/system/src/org/chromium/mojo/system/impl/HandleBase.java
index a8870a8..4d149a4 100644
--- a/mojo/android/system/src/org/chromium/mojo/system/impl/HandleBase.java
+++ b/mojo/android/system/src/org/chromium/mojo/system/impl/HandleBase.java
@@ -7,8 +7,7 @@
import android.util.Log;
import org.chromium.mojo.system.Core;
-import org.chromium.mojo.system.Core.HandleSignals;
-import org.chromium.mojo.system.Core.WaitResult;
+import org.chromium.mojo.system.Core.HandleSignalsState;
import org.chromium.mojo.system.Handle;
import org.chromium.mojo.system.UntypedHandle;
@@ -63,11 +62,11 @@
}
/**
- * @see org.chromium.mojo.system.Handle#wait(HandleSignals, long)
+ * @see org.chromium.mojo.system.Handle#querySignalsState()
*/
@Override
- public WaitResult wait(HandleSignals signals, long deadline) {
- return mCore.wait(this, signals, deadline);
+ public HandleSignalsState querySignalsState() {
+ return mCore.queryHandleSignalsState(mMojoHandle);
}
/**
diff --git a/mojo/edk/embedder/entrypoints.cc b/mojo/edk/embedder/entrypoints.cc
index ecf1630..5c149d9 100644
--- a/mojo/edk/embedder/entrypoints.cc
+++ b/mojo/edk/embedder/entrypoints.cc
@@ -28,6 +28,12 @@
return g_core->Close(handle);
}
+MojoResult MojoQueryHandleSignalsStateImpl(
+ MojoHandle handle,
+ MojoHandleSignalsState* signals_state) {
+ return g_core->QueryHandleSignalsState(handle, signals_state);
+}
+
MojoResult MojoWaitImpl(MojoHandle handle,
MojoHandleSignals signals,
MojoDeadline deadline,
@@ -281,6 +287,7 @@
MojoSystemThunks system_thunks = {sizeof(MojoSystemThunks),
MojoGetTimeTicksNowImpl,
MojoCloseImpl,
+ MojoQueryHandleSignalsStateImpl,
MojoWaitImpl,
MojoWaitManyImpl,
MojoCreateMessagePipeImpl,
diff --git a/mojo/edk/js/core.cc b/mojo/edk/js/core.cc
index f3eec8c..db9a395 100644
--- a/mojo/edk/js/core.cc
+++ b/mojo/edk/js/core.cc
@@ -35,6 +35,20 @@
return MOJO_RESULT_OK;
}
+gin::Dictionary QueryHandleSignalsState(const gin::Arguments& args,
+ mojo::Handle handle) {
+ gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
+ if (!handle.is_valid()) {
+ dictionary.Set("result", MOJO_RESULT_INVALID_ARGUMENT);
+ } else {
+ HandleSignalsState state = handle.QuerySignalsState();
+ dictionary.Set("result", MOJO_RESULT_OK);
+ dictionary.Set("satisfiedSignals", state.satisfied_signals);
+ dictionary.Set("satisfiableSignals", state.satisfiable_signals);
+ }
+ return dictionary;
+}
+
gin::Dictionary WaitHandle(const gin::Arguments& args,
mojo::Handle handle,
MojoHandleSignals signals,
@@ -388,6 +402,7 @@
// TODO(mpcomplete): Should these just be methods on the JS Handle
// object?
.SetMethod("close", CloseHandle)
+ .SetMethod("queryHandleSignalsState", QueryHandleSignalsState)
.SetMethod("wait", WaitHandle)
.SetMethod("waitMany", WaitMany)
.SetMethod("createMessagePipe", CreateMessagePipe)
diff --git a/mojo/edk/system/awakable_list.cc b/mojo/edk/system/awakable_list.cc
index 429e691..f38d580 100644
--- a/mojo/edk/system/awakable_list.cc
+++ b/mojo/edk/system/awakable_list.cc
@@ -8,7 +8,6 @@
#include "base/logging.h"
#include "mojo/edk/system/awakable.h"
-#include "mojo/edk/system/handle_signals_state.h"
namespace mojo {
namespace edk {
diff --git a/mojo/edk/system/awakable_list.h b/mojo/edk/system/awakable_list.h
index 34d6b06..d400b38 100644
--- a/mojo/edk/system/awakable_list.h
+++ b/mojo/edk/system/awakable_list.h
@@ -13,12 +13,12 @@
#include "base/macros.h"
#include "mojo/edk/system/system_impl_export.h"
#include "mojo/public/c/system/types.h"
+#include "mojo/public/cpp/system/handle_signals_state.h"
namespace mojo {
namespace edk {
class Awakable;
-struct HandleSignalsState;
// |AwakableList| tracks all the |Waiter|s that are waiting on a given
// handle/|Dispatcher|. There should be a |AwakableList| for each handle that
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc
index cfe01fa..263f9cd 100644
--- a/mojo/edk/system/core.cc
+++ b/mojo/edk/system/core.cc
@@ -378,6 +378,17 @@
return MOJO_RESULT_OK;
}
+MojoResult Core::QueryHandleSignalsState(
+ MojoHandle handle,
+ MojoHandleSignalsState* signals_state) {
+ RequestContext request_context;
+ scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle);
+ if (!dispatcher || !signals_state)
+ return MOJO_RESULT_INVALID_ARGUMENT;
+ *signals_state = dispatcher->GetHandleSignalsState();
+ return MOJO_RESULT_OK;
+}
+
MojoResult Core::Wait(MojoHandle handle,
MojoHandleSignals signals,
MojoDeadline deadline,
diff --git a/mojo/edk/system/core.h b/mojo/edk/system/core.h
index 2ef9b7f..ab94951 100644
--- a/mojo/edk/system/core.h
+++ b/mojo/edk/system/core.h
@@ -136,6 +136,8 @@
// "mojo/public/c/system/functions.h":
MojoTimeTicks GetTimeTicksNow();
MojoResult Close(MojoHandle handle);
+ MojoResult QueryHandleSignalsState(MojoHandle handle,
+ MojoHandleSignalsState* signals_state);
MojoResult Wait(MojoHandle handle,
MojoHandleSignals signals,
MojoDeadline deadline,
diff --git a/mojo/edk/system/data_pipe_unittest.cc b/mojo/edk/system/data_pipe_unittest.cc
index 1147496..b04bebd 100644
--- a/mojo/edk/system/data_pipe_unittest.cc
+++ b/mojo/edk/system/data_pipe_unittest.cc
@@ -162,8 +162,7 @@
// Now wait for the other side to become readable.
MojoHandleSignalsState state;
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &state));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &state));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
state.satisfied_signals);
@@ -249,8 +248,7 @@
// Wait.
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
@@ -337,19 +335,12 @@
Create(&options);
MojoHandleSignalsState hss;
- // Never readable.
- hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- MojoWait(producer_, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
+ // Never readable. Already writable.
+ hss = GetSignalsState(producer_);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
hss.satisfiable_signals);
- // Already writable.
- hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(producer_, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
-
// Write two elements.
int32_t elements[2] = {123, 456};
uint32_t num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
@@ -358,8 +349,7 @@
// Wait for data to become available to the consumer.
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
@@ -419,11 +409,7 @@
// It should now be never-writable.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(producer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, &hss));
- hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- MojoWait(producer_, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
+ WaitForSignals(producer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
}
@@ -444,8 +430,7 @@
// It should be signaled.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(producer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(producer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
}
@@ -466,8 +451,7 @@
// It should be signaled.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
}
@@ -485,8 +469,7 @@
// Never writable.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_WRITABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_WRITABLE, &hss));
EXPECT_EQ(0u, hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
@@ -500,8 +483,7 @@
// Wait for readability.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
@@ -516,8 +498,7 @@
// Should still be readable.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
@@ -534,8 +515,7 @@
// Should still be readable.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
@@ -559,8 +539,7 @@
// Waiting should now succeed.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
@@ -573,8 +552,7 @@
// Should still be readable.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_TRUE(hss.satisfied_signals & (MOJO_HANDLE_SIGNAL_READABLE |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
@@ -584,8 +562,7 @@
// Wait for the peer closed signal.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE |
MOJO_HANDLE_SIGNAL_PEER_CLOSED,
hss.satisfied_signals);
@@ -605,8 +582,7 @@
// Should be never-readable.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
}
@@ -625,11 +601,10 @@
EXPECT_EQ(MOJO_RESULT_OK, WriteData(elements, &num_bytes, true));
// The consumer handle should appear to be readable and have new data.
- EXPECT_EQ(MOJO_RESULT_OK, MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, nullptr));
EXPECT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE));
+ EXPECT_TRUE(GetSignalsState(consumer_).satisfied_signals &
+ MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE);
// Now try to read a minimum of 6 elements.
int32_t read_elements[6];
@@ -638,35 +613,30 @@
MojoReadData(consumer_, read_elements, &num_read_bytes,
MOJO_READ_DATA_FLAG_ALL_OR_NONE));
- // The consumer should still appear to be readable, but not with new data.
- EXPECT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE, 0, nullptr));
- EXPECT_EQ(
- MOJO_RESULT_DEADLINE_EXCEEDED,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE, 0, nullptr));
+ // The consumer should still appear to be readable but not with new data.
+ EXPECT_TRUE(GetSignalsState(consumer_).satisfied_signals &
+ MOJO_HANDLE_SIGNAL_READABLE);
+ EXPECT_FALSE(GetSignalsState(consumer_).satisfied_signals &
+ MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE);
// Write four more elements.
EXPECT_EQ(MOJO_RESULT_OK, WriteData(elements, &num_bytes, true));
EXPECT_EQ(MOJO_RESULT_OK, WriteData(elements, &num_bytes, true));
- // The consumer handle should once again appear to be readable with new data.
- EXPECT_EQ(MOJO_RESULT_OK, MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ // The consumer handle should once again appear to be readable.
EXPECT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE));
- // Read should succeed this time.
+ // Try again to read a minimum of 6 elements. Should succeed this time.
EXPECT_EQ(MOJO_RESULT_OK,
MojoReadData(consumer_, read_elements, &num_read_bytes,
MOJO_READ_DATA_FLAG_ALL_OR_NONE));
- // And once again the consumer is unreadable.
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE, 0, nullptr));
- EXPECT_EQ(
- MOJO_RESULT_DEADLINE_EXCEEDED,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE, 0, nullptr));
+ // And now the consumer is unreadable.
+ EXPECT_FALSE(GetSignalsState(consumer_).satisfied_signals &
+ MOJO_HANDLE_SIGNAL_READABLE);
+ EXPECT_FALSE(GetSignalsState(consumer_).satisfied_signals &
+ MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE);
}
// Test with two-phase APIs and also closing the producer with an active
@@ -697,8 +667,7 @@
// Wait for readability.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
@@ -719,8 +688,7 @@
// Should still be readable.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
@@ -743,8 +711,7 @@
// Should be never-readable.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
}
@@ -761,9 +728,7 @@
MojoHandleSignalsState hss;
// It should be writable.
- hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(producer_, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
+ hss = GetSignalsState(producer_);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
hss.satisfiable_signals);
@@ -775,17 +740,13 @@
EXPECT_GE(num_bytes, static_cast<uint32_t>(1u * sizeof(int32_t)));
// At this point, it shouldn't be writable.
- hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
- MojoWait(producer_, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
+ hss = GetSignalsState(producer_);
ASSERT_EQ(0u, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
hss.satisfiable_signals);
// It shouldn't be readable yet either (we'll wait later).
- hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
+ hss = GetSignalsState(consumer_);
ASSERT_EQ(0u, hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
@@ -795,9 +756,7 @@
ASSERT_EQ(MOJO_RESULT_OK, EndWriteData(1u * sizeof(int32_t)));
// It should immediately be writable again.
- hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(producer_, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
+ hss = GetSignalsState(producer_);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
hss.satisfiable_signals);
@@ -805,8 +764,7 @@
// It should become readable.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
@@ -824,8 +782,7 @@
// It should be readable.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
@@ -843,17 +800,13 @@
ASSERT_EQ(static_cast<uint32_t>(1u * sizeof(int32_t)), num_bytes);
// At this point, it should still be writable.
- hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(producer_, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
+ hss = GetSignalsState(producer_);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
hss.satisfiable_signals);
// But not readable.
- hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
+ hss = GetSignalsState(consumer_);
ASSERT_EQ(0u, hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
@@ -863,9 +816,7 @@
ASSERT_EQ(MOJO_RESULT_OK, EndReadData(0u));
// It should be readable again.
- hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
+ hss = GetSignalsState(consumer_);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
@@ -911,8 +862,7 @@
// of data to become available.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE |
@@ -1002,8 +952,7 @@
// Wait.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
@@ -1067,8 +1016,7 @@
// Wait for data.
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_TRUE(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
@@ -1095,8 +1043,7 @@
while (total_num_bytes < 90) {
// Wait to write.
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(producer_, MOJO_HANDLE_SIGNAL_WRITABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(producer_, MOJO_HANDLE_SIGNAL_WRITABLE, &hss));
ASSERT_EQ(hss.satisfied_signals, MOJO_HANDLE_SIGNAL_WRITABLE);
ASSERT_EQ(hss.satisfiable_signals,
MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED);
@@ -1231,8 +1178,7 @@
// TODO(vtl): (See corresponding TODO in AllOrNone.)
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
@@ -1252,8 +1198,7 @@
// Wait for producer to know that the consumer is closed.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(producer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(producer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
@@ -1323,8 +1268,7 @@
// must also know about all the data that was sent.)
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
@@ -1384,8 +1328,7 @@
// Wait for the data.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
@@ -1411,8 +1354,7 @@
// must also have received the extra data).
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
@@ -1499,8 +1441,7 @@
// TODO(vtl): (See corresponding TODO in AllOrNone.)
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
@@ -1569,8 +1510,7 @@
// Wait for the data.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
@@ -1594,8 +1534,8 @@
MojoWriteMessage(pipe0, nullptr, 0, &producer_, 1,
MOJO_WRITE_MESSAGE_FLAG_NONE));
producer_ = MOJO_HANDLE_INVALID;
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe1, MOJO_HANDLE_SIGNAL_READABLE, &hss));
uint32_t num_handles = 1;
ASSERT_EQ(MOJO_RESULT_OK,
MojoReadMessage(pipe1, nullptr, 0, &producer_, &num_handles,
@@ -1612,8 +1552,7 @@
// Wait for it.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
@@ -1653,8 +1592,7 @@
// Now wait for the other side to become readable and to see the peer closed.
MojoHandleSignalsState state;
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, &state));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &state));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
state.satisfied_signals);
@@ -1671,8 +1609,8 @@
MojoWriteMessage(pipe0, nullptr, 0, &consumer_, 1,
MOJO_WRITE_MESSAGE_FLAG_NONE));
consumer_ = MOJO_HANDLE_INVALID;
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &state));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe1, MOJO_HANDLE_SIGNAL_READABLE, &state));
uint32_t num_handles = 1;
ASSERT_EQ(MOJO_RESULT_OK,
MojoReadMessage(pipe1, nullptr, 0, &consumer_, &num_handles,
@@ -1680,8 +1618,7 @@
ASSERT_EQ(num_handles, 1u);
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, &state));
+ WaitForSignals(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &state));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
state.satisfied_signals);
@@ -1716,8 +1653,8 @@
}
MojoHandleSignalsState hss = MojoHandleSignalsState();
- EXPECT_EQ(MOJO_RESULT_OK, MojoWait(producer, MOJO_HANDLE_SIGNAL_WRITABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ EXPECT_EQ(MOJO_RESULT_OK, test::MojoTestBase::WaitForSignals(
+ producer, MOJO_HANDLE_SIGNAL_WRITABLE, &hss));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
hss.satisfiable_signals);
@@ -1754,8 +1691,8 @@
}
MojoHandleSignalsState hss = MojoHandleSignalsState();
- EXPECT_EQ(MOJO_RESULT_OK, MojoWait(consumer, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ EXPECT_EQ(MOJO_RESULT_OK, test::MojoTestBase::WaitForSignals(
+ consumer, MOJO_HANDLE_SIGNAL_READABLE, &hss));
// Peer could have become closed while we're still waiting for data.
EXPECT_TRUE(MOJO_HANDLE_SIGNAL_READABLE & hss.satisfied_signals);
EXPECT_TRUE(hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
@@ -1814,8 +1751,8 @@
// Receive the consumer from the other side.
producer_ = MOJO_HANDLE_INVALID;
MojoHandleSignalsState hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(server_mp, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(server_mp, MOJO_HANDLE_SIGNAL_READABLE, &hss));
MojoHandle handles[2];
uint32_t num_handles = arraysize(handles);
ASSERT_EQ(MOJO_RESULT_OK,
@@ -1844,8 +1781,8 @@
// Receive the data pipe from the other side.
MojoHandle consumer = MOJO_HANDLE_INVALID;
MojoHandleSignalsState hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(client_mp, MOJO_HANDLE_SIGNAL_READABLE, &hss));
MojoHandle handles[2];
uint32_t num_handles = arraysize(handles);
ASSERT_EQ(MOJO_RESULT_OK,
@@ -1880,8 +1817,8 @@
// Receive the producer from the other side.
MojoHandle producer = MOJO_HANDLE_INVALID;
hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(client_mp, MOJO_HANDLE_SIGNAL_READABLE, &hss));
num_handles = arraysize(handles);
ASSERT_EQ(MOJO_RESULT_OK,
MojoReadMessage(client_mp, nullptr, 0, handles, &num_handles,
@@ -1921,8 +1858,7 @@
std::string expected_message = ReadMessageWithHandles(h, &c, 1);
// Wait for the consumer to become readable.
- EXPECT_EQ(MOJO_RESULT_OK, MojoWait(c, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(c, MOJO_HANDLE_SIGNAL_READABLE));
// Drain the consumer and expect to find the given message.
uint32_t num_bytes = static_cast<uint32_t>(expected_message.size());
@@ -1989,8 +1925,7 @@
std::string expected_message = ReadMessageWithHandles(child, &c, 1);
// Wait for the consumer to become readable.
- EXPECT_EQ(MOJO_RESULT_OK, MojoWait(c, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(c, MOJO_HANDLE_SIGNAL_READABLE));
// Drain the consumer and expect to find the given message.
uint32_t num_bytes = static_cast<uint32_t>(expected_message.size());
@@ -2017,15 +1952,13 @@
MojoHandle* producers = &handles[0];
MojoHandle* consumers = &handles[3];
- // Wait on producer 0 using MojoWait.
+ // Wait on producer 0
EXPECT_EQ(MOJO_RESULT_OK,
- MojoWait(producers[0], MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ WaitForSignals(producers[0], MOJO_HANDLE_SIGNAL_PEER_CLOSED));
- // Wait on consumer 0 using MojoWait.
+ // Wait on consumer 0
EXPECT_EQ(MOJO_RESULT_OK,
- MojoWait(consumers[0], MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ WaitForSignals(consumers[0], MOJO_HANDLE_SIGNAL_PEER_CLOSED));
base::MessageLoop message_loop;
diff --git a/mojo/edk/system/handle_signals_state.h b/mojo/edk/system/handle_signals_state.h
index 1c47a28..f241278 100644
--- a/mojo/edk/system/handle_signals_state.h
+++ b/mojo/edk/system/handle_signals_state.h
@@ -5,45 +5,9 @@
#ifndef MOJO_EDK_SYSTEM_HANDLE_SIGNALS_STATE_H_
#define MOJO_EDK_SYSTEM_HANDLE_SIGNALS_STATE_H_
-#include "mojo/edk/system/system_impl_export.h"
-#include "mojo/public/c/system/types.h"
+#include "mojo/public/cpp/system/handle_signals_state.h"
-namespace mojo {
-namespace edk {
-
-// Just "add" some constructors and methods to the C struct
-// |MojoHandleSignalsState| (for convenience). This should add no overhead.
-struct MOJO_SYSTEM_IMPL_EXPORT HandleSignalsState final
- : public MojoHandleSignalsState {
- HandleSignalsState() {
- satisfied_signals = MOJO_HANDLE_SIGNAL_NONE;
- satisfiable_signals = MOJO_HANDLE_SIGNAL_NONE;
- }
- HandleSignalsState(MojoHandleSignals satisfied,
- MojoHandleSignals satisfiable) {
- satisfied_signals = satisfied;
- satisfiable_signals = satisfiable;
- }
-
- bool equals(const HandleSignalsState& other) const {
- return satisfied_signals == other.satisfied_signals &&
- satisfiable_signals == other.satisfiable_signals;
- }
-
- bool satisfies(MojoHandleSignals signals) const {
- return !!(satisfied_signals & signals);
- }
-
- bool can_satisfy(MojoHandleSignals signals) const {
- return !!(satisfiable_signals & signals);
- }
-
- // (Copy and assignment allowed.)
-};
-static_assert(sizeof(HandleSignalsState) == sizeof(MojoHandleSignalsState),
- "HandleSignalsState should add no overhead");
-
-} // namespace edk
-} // namespace mojo
+// TODO(rockot): Remove this header and use the C++ system library type
+// directly inside the EDK.
#endif // MOJO_EDK_SYSTEM_HANDLE_SIGNALS_STATE_H_
diff --git a/mojo/edk/system/message_pipe_perftest.cc b/mojo/edk/system/message_pipe_perftest.cc
index a6ce370..9866c47 100644
--- a/mojo/edk/system/message_pipe_perftest.cc
+++ b/mojo/edk/system/message_pipe_perftest.cc
@@ -47,8 +47,7 @@
0, MOJO_WRITE_MESSAGE_FLAG_NONE),
MOJO_RESULT_OK);
HandleSignalsState hss;
- CHECK_EQ(MojoWait(mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
- &hss),
+ CHECK_EQ(WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss),
MOJO_RESULT_OK);
uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer_.size());
CHECK_EQ(MojoReadMessage(mp, &read_buffer_[0], &read_buffer_size, nullptr,
@@ -98,9 +97,7 @@
while (true) {
// Wait for our end of the message pipe to be readable.
HandleSignalsState hss;
- MojoResult result =
- MojoWait(mp, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss);
+ MojoResult result = WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss);
if (result != MOJO_RESULT_OK) {
rv = result;
break;
diff --git a/mojo/edk/system/message_pipe_unittest.cc b/mojo/edk/system/message_pipe_unittest.cc
index 8f48950..e6f1ff6 100644
--- a/mojo/edk/system/message_pipe_unittest.cc
+++ b/mojo/edk/system/message_pipe_unittest.cc
@@ -100,8 +100,8 @@
ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, sizeof(buffer[0])));
MojoHandleSignalsState state;
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &state));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, &state));
// Read from port 0.
buffer[0] = 123;
@@ -124,8 +124,8 @@
buffer[1] = 0;
ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe0_, buffer, sizeof(buffer[0])));
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &state));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_READABLE, &state));
// Read from port 1 with buffer size 0 (should get the size of next message).
// Also test that giving a null buffer is okay when the buffer size is 0.
@@ -154,8 +154,8 @@
ASSERT_EQ(123456789, buffer[0]);
ASSERT_EQ(456, buffer[1]);
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &state));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_READABLE, &state));
// Read again from port 1.
buffer[0] = 123;
@@ -179,8 +179,8 @@
MojoClose(pipe0_);
pipe0_ = MOJO_HANDLE_INVALID;
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, &state));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &state));
// Try to write from port 1 (to port 0).
buffer[0] = 456789012;
@@ -215,8 +215,8 @@
}
MojoHandleSignalsState state;
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &state));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, &state));
// Port 0 shouldn't be empty.
buffer_size = 0;
@@ -241,8 +241,8 @@
ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, sizeof(buffer[0])));
MojoHandleSignalsState state;
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &state));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, &state));
// Read/discard from port 0 (no buffer); get size.
buffer_size = 0;
@@ -261,8 +261,8 @@
ASSERT_EQ(MOJO_RESULT_OK,
WriteMessage(pipe1_, buffer, sizeof(buffer[0])));
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &state));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, &state));
// Read from port 0 (buffer big enough).
buffer[0] = 123;
@@ -283,8 +283,8 @@
buffer[1] = 0;
ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, sizeof(buffer[0])));
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &state));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, &state));
// Read/discard from port 0 (buffer too small); get size.
buffer_size = 1;
@@ -302,8 +302,8 @@
buffer[1] = 0;
ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, sizeof(buffer[0])));
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &state));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, &state));
// Discard from port 0.
buffer_size = 1;
@@ -323,41 +323,27 @@
const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
uint32_t buffer_size;
- // Always writable (until the other port is closed).
- hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_WRITABLE, 0,
- &hss));
+ // Always writable (until the other port is closed). Not yet readable. Peer
+ // not closed.
+ hss = GetSignalsState(pipe0_);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
hss = MojoHandleSignalsState();
- // Not yet readable.
- ASSERT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
- MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
- ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
- ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
-
- // The peer is not closed.
- hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
- MojoWait(pipe0_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, 0, &hss));
- ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
- ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
-
// Write from port 0 (to port 1), to make port 1 readable.
buffer[0] = 123456789;
ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe0_, buffer, kBufferSize));
// Port 1 should already be readable now.
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
hss.satisfied_signals);
ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
// ... and still writable.
hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_WRITABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_WRITABLE, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
hss.satisfied_signals);
ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
@@ -368,8 +354,8 @@
// Port 1 should be signaled with peer closed.
hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
@@ -379,8 +365,7 @@
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_WRITABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_WRITABLE, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
@@ -388,8 +373,8 @@
// But it should still be readable.
hss = MojoHandleSignalsState();
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
@@ -404,8 +389,7 @@
// Now port 1 should no longer be readable.
hss = MojoHandleSignalsState();
ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- MojoWait(pipe1_, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_READABLE, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
}
@@ -453,9 +437,7 @@
EXPECT_EQ(MOJO_RESULT_OK,
MojoWriteMessageNew(a, message, MOJO_WRITE_MESSAGE_FLAG_NONE));
- EXPECT_EQ(MOJO_RESULT_OK,
- MojoWait(b, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
- nullptr));
+ EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(b, MOJO_HANDLE_SIGNAL_READABLE));
uint32_t num_bytes = 0;
uint32_t num_handles = 0;
EXPECT_EQ(MOJO_RESULT_OK,
@@ -489,8 +471,7 @@
WriteMessageWithHandles(h, "", handles, kPingPongHandlesPerIteration);
}
- EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE));
char msg[4];
uint32_t num_bytes = 4;
EXPECT_EQ(MOJO_RESULT_OK, ReadMessage(h, msg, &num_bytes));
@@ -675,9 +656,7 @@
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(b));
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c));
- EXPECT_EQ(MOJO_RESULT_OK, MojoWait(d, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, nullptr));
-
+ EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(d, MOJO_HANDLE_SIGNAL_PEER_CLOSED));
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(d));
}
@@ -700,9 +679,7 @@
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c));
EXPECT_EQ(kTestMessage, ReadMessage(d));
- EXPECT_EQ(MOJO_RESULT_OK, MojoWait(d, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, nullptr));
-
+ EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(d, MOJO_HANDLE_SIGNAL_PEER_CLOSED));
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(d));
}
diff --git a/mojo/edk/system/multiprocess_message_pipe_unittest.cc b/mojo/edk/system/multiprocess_message_pipe_unittest.cc
index f8e29d6..3b521cc 100644
--- a/mojo/edk/system/multiprocess_message_pipe_unittest.cc
+++ b/mojo/edk/system/multiprocess_message_pipe_unittest.cc
@@ -91,9 +91,7 @@
for (;; rv = (rv + 1) % 100) {
// Wait for our end of the message pipe to be readable.
HandleSignalsState hss;
- MojoResult result =
- MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss);
+ MojoResult result = WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss);
if (result != MOJO_RESULT_OK) {
// It was closed, probably.
CHECK_EQ(result, MOJO_RESULT_FAILED_PRECONDITION);
@@ -139,8 +137,7 @@
HandleSignalsState hss;
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss));
// The child may or may not have closed its end of the message pipe and died
// (and we may or may not know it yet), so our end may or may not appear as
// writable.
@@ -179,8 +176,7 @@
for (size_t i = 0; i < kNumMessages; i++) {
HandleSignalsState hss;
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss));
// The child may or may not have closed its end of the message pipe and
// died (and we may or may not know it yet), so our end may or may not
// appear as writable.
@@ -208,8 +204,7 @@
// "quitquitquit").
HandleSignalsState hss;
ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
END_CHILD_AND_EXPECT_EXIT_CODE(static_cast<int>(kNumMessages % 100));
@@ -219,8 +214,7 @@
h) {
// Wait for the first message from our parent.
HandleSignalsState hss;
- CHECK_EQ(MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss),
+ CHECK_EQ(WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss),
MOJO_RESULT_OK);
// In this test, the parent definitely doesn't close its end of the message
// pipe before we do.
@@ -265,8 +259,7 @@
// Now wait for our parent to send us a message.
hss = HandleSignalsState();
- CHECK_EQ(MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss),
+ CHECK_EQ(WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss),
MOJO_RESULT_OK);
CHECK_EQ(hss.satisfied_signals,
MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
@@ -322,8 +315,7 @@
// Wait for a message from the child.
HandleSignalsState hss;
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
@@ -359,8 +351,7 @@
// Wait for |h| to become readable, which should fail.
hss = HandleSignalsState();
ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
END_CHILD()
@@ -369,8 +360,7 @@
DEFINE_TEST_CLIENT_WITH_PIPE(CheckPlatformHandleFile,
MultiprocessMessagePipeTest, h) {
HandleSignalsState hss;
- CHECK_EQ(MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss),
+ CHECK_EQ(WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss),
MOJO_RESULT_OK);
CHECK_EQ(hss.satisfied_signals,
MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
@@ -455,8 +445,7 @@
// Wait for it to become readable, which should fail.
HandleSignalsState hss;
ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss));
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
END_CHILD()
@@ -474,8 +463,7 @@
DEFINE_TEST_CLIENT_WITH_PIPE(CheckMessagePipe, MultiprocessMessagePipeTest, h) {
// Wait for the first message from our parent.
HandleSignalsState hss;
- CHECK_EQ(MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss),
+ CHECK_EQ(WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss),
MOJO_RESULT_OK);
// In this test, the parent definitely doesn't close its end of the message
// pipe before we do.
@@ -495,8 +483,7 @@
CHECK_EQ(num_handlers, 1u);
// Read data from the received message pipe.
- CHECK_EQ(MojoWait(handles[0], MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss),
+ CHECK_EQ(WaitForSignals(handles[0], MOJO_HANDLE_SIGNAL_READABLE, &hss),
MOJO_RESULT_OK);
CHECK_EQ(hss.satisfied_signals,
MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
@@ -547,8 +534,7 @@
// Wait for a message from the child.
HandleSignalsState hss;
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(mp1, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
@@ -585,8 +571,7 @@
// Wait for a message from the child.
HandleSignalsState hss;
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(mp1, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
@@ -604,8 +589,7 @@
DEFINE_TEST_CLIENT_WITH_PIPE(DataPipeConsumer, MultiprocessMessagePipeTest, h) {
// Wait for the first message from our parent.
HandleSignalsState hss;
- CHECK_EQ(MojoWait(h, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss),
+ CHECK_EQ(WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss),
MOJO_RESULT_OK);
// In this test, the parent definitely doesn't close its end of the message
// pipe before we do.
@@ -625,8 +609,7 @@
CHECK_EQ(num_handlers, 1u);
// Read data from the received message pipe.
- CHECK_EQ(MojoWait(handles[0], MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss),
+ CHECK_EQ(WaitForSignals(handles[0], MOJO_HANDLE_SIGNAL_READABLE, &hss),
MOJO_RESULT_OK);
CHECK_EQ(hss.satisfied_signals,
MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
@@ -677,8 +660,7 @@
// Wait for a message from the child.
HandleSignalsState hss;
ASSERT_EQ(MOJO_RESULT_OK,
- MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, &hss));
+ WaitForSignals(mp1, MOJO_HANDLE_SIGNAL_READABLE, &hss));
EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
@@ -924,9 +906,7 @@
EXPECT_EQ("bye", ReadMessage(p0));
// We should still be able to observe peer closure from the other end.
- EXPECT_EQ(MOJO_RESULT_OK,
- MojoWait(p0, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(p0, MOJO_HANDLE_SIGNAL_PEER_CLOSED));
}
// Parses commands from the parent pipe and does whatever it's asked to do.
@@ -1110,10 +1090,7 @@
MultiprocessMessagePipeTest, h) {
MojoHandle p;
EXPECT_EQ("foo", ReadMessageWithHandles(h, &p, 1));
-
- auto result = MojoWait(p, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, nullptr);
- EXPECT_EQ(MOJO_RESULT_OK, result);
+ EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(p, MOJO_HANDLE_SIGNAL_PEER_CLOSED));
}
TEST_P(MultiprocessMessagePipeTestWithPeerSupport, SendPipeThenClosePeer) {
@@ -1159,9 +1136,8 @@
ReadMessageWithHandles(application_client, &service_client, 1));
// Wait for the service client to signal closure.
- EXPECT_EQ(MOJO_RESULT_OK, MojoWait(service_client,
- MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ EXPECT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(service_client, MOJO_HANDLE_SIGNAL_PEER_CLOSED));
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(service_client));
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(application_client));
@@ -1207,8 +1183,7 @@
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(b));
// We should be able to detect peer closure on |a|.
- EXPECT_EQ(MOJO_RESULT_OK, MojoWait(a, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(a, MOJO_HANDLE_SIGNAL_PEER_CLOSED));
}
DEFINE_TEST_CLIENT_TEST_WITH_PIPE(WriteCloseSendPeerClient,
@@ -1251,8 +1226,8 @@
EXPECT_EQ("qux", ReadMessage(p));
// Expect to have peer closure signaled.
- EXPECT_EQ(MOJO_RESULT_OK, MojoWait(p, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ EXPECT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(p, MOJO_HANDLE_SIGNAL_PEER_CLOSED));
WriteMessage(h, "quit");
END_CHILD()
@@ -1265,9 +1240,8 @@
MojoHandle handles[4];
EXPECT_EQ("o_O", ReadMessageWithHandles(parent, handles, 4));
- // Wait on handle 0 using MojoWait.
- EXPECT_EQ(MOJO_RESULT_OK, MojoWait(handles[0], MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ EXPECT_EQ(MOJO_RESULT_OK,
+ WaitForSignals(handles[0], MOJO_HANDLE_SIGNAL_PEER_CLOSED));
base::MessageLoop message_loop;
@@ -1349,8 +1323,7 @@
WriteMessageWithHandles(child2, "hi", &d, 1);
// Read a message from the pipe we sent to child1 and flag it as bad.
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(a, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ ASSERT_EQ(MOJO_RESULT_OK, WaitForSignals(a, MOJO_HANDLE_SIGNAL_READABLE));
uint32_t num_bytes = 0;
MojoMessageHandle message;
ASSERT_EQ(MOJO_RESULT_OK,
@@ -1362,8 +1335,7 @@
EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message));
// Read a message from the pipe we sent to child2 and flag it as bad.
- ASSERT_EQ(MOJO_RESULT_OK, MojoWait(c, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, nullptr));
+ ASSERT_EQ(MOJO_RESULT_OK, WaitForSignals(c, MOJO_HANDLE_SIGNAL_READABLE));
ASSERT_EQ(MOJO_RESULT_OK,
MojoReadMessageNew(c, &message, &num_bytes, nullptr, 0,
MOJO_READ_MESSAGE_FLAG_NONE));
diff --git a/mojo/edk/system/signals_unittest.cc b/mojo/edk/system/signals_unittest.cc
new file mode 100644
index 0000000..e8b0cd1
--- /dev/null
+++ b/mojo/edk/system/signals_unittest.cc
@@ -0,0 +1,76 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/edk/test/mojo_test_base.h"
+#include "mojo/public/c/system/buffer.h"
+#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/c/system/types.h"
+
+namespace mojo {
+namespace edk {
+namespace {
+
+using SignalsTest = test::MojoTestBase;
+
+TEST_F(SignalsTest, QueryInvalidArguments) {
+ MojoHandleSignalsState state = {0, 0};
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+ MojoQueryHandleSignalsState(MOJO_HANDLE_INVALID, &state));
+
+ MojoHandle a, b;
+ CreateMessagePipe(&a, &b);
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+ MojoQueryHandleSignalsState(a, nullptr));
+}
+
+TEST_F(SignalsTest, QueryMessagePipeSignals) {
+ MojoHandleSignalsState state = {0, 0};
+
+ MojoHandle a, b;
+ CreateMessagePipe(&a, &b);
+
+ EXPECT_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(a, &state));
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE |
+ MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+ state.satisfiable_signals);
+
+ EXPECT_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(b, &state));
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE |
+ MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+ state.satisfiable_signals);
+
+ WriteMessage(a, "ok");
+ EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(b, MOJO_HANDLE_SIGNAL_READABLE));
+
+ EXPECT_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(b, &state));
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
+ state.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE |
+ MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+ state.satisfiable_signals);
+
+ EXPECT_EQ("ok", ReadMessage(b));
+
+ EXPECT_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(b, &state));
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE |
+ MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+ state.satisfiable_signals);
+
+ EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a));
+
+ EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(b, MOJO_HANDLE_SIGNAL_PEER_CLOSED));
+
+ EXPECT_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(b, &state));
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals);
+}
+
+} // namespace
+} // namespace edk
+} // namespace mojo
diff --git a/mojo/edk/test/mojo_test_base.cc b/mojo/edk/test/mojo_test_base.cc
index f1032d7..d7d3b2a 100644
--- a/mojo/edk/test/mojo_test_base.cc
+++ b/mojo/edk/test/mojo_test_base.cc
@@ -5,13 +5,16 @@
#include "mojo/edk/test/mojo_test_base.h"
#include "base/memory/ptr_util.h"
+#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/synchronization/waitable_event.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/system/handle_signals_state.h"
#include "mojo/public/c/system/buffer.h"
#include "mojo/public/c/system/data_pipe.h"
#include "mojo/public/c/system/functions.h"
+#include "mojo/public/c/system/watcher.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_MACOSX) && !defined(OS_IOS)
@@ -22,6 +25,103 @@
namespace edk {
namespace test {
+namespace {
+
+class Waiter {
+ public:
+ Waiter() {}
+ ~Waiter() {}
+
+ MojoResult Wait(MojoHandle handle,
+ MojoHandleSignals signals,
+ MojoHandleSignalsState* state) {
+ MojoHandle watcher;
+ MojoCreateWatcher(&Context::OnNotification, &watcher);
+
+ context_ = new Context();
+
+ // Balanced by OnNotification in the |MOJO_RESULT_CANCELLED| case.
+ context_->AddRef();
+
+ MojoResult rv = MojoWatch(watcher, handle, signals,
+ reinterpret_cast<uintptr_t>(context_.get()));
+ DCHECK_EQ(MOJO_RESULT_OK, rv);
+
+ uint32_t num_ready_contexts = 1;
+ uintptr_t ready_context;
+ MojoResult ready_result;
+ MojoHandleSignalsState ready_state;
+ rv = MojoArmWatcher(watcher, &num_ready_contexts, &ready_context,
+ &ready_result, &ready_state);
+ if (rv == MOJO_RESULT_FAILED_PRECONDITION) {
+ MojoClose(watcher);
+ DCHECK_EQ(1u, num_ready_contexts);
+ if (state)
+ *state = ready_state;
+ return ready_result;
+ }
+
+ // Wait for the first notification.
+ context_->event().Wait();
+
+ ready_result = context_->wait_result();
+ DCHECK_NE(MOJO_RESULT_UNKNOWN, ready_result);
+
+ if (state)
+ *state = context_->wait_state();
+
+ MojoClose(watcher);
+
+ return ready_result;
+ }
+
+ private:
+ class Context : public base::RefCountedThreadSafe<Context> {
+ public:
+ Context()
+ : event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
+ base::WaitableEvent::InitialState::NOT_SIGNALED) {}
+
+ base::WaitableEvent& event() { return event_; }
+ MojoResult wait_result() const { return wait_result_; }
+ MojoHandleSignalsState wait_state() const { return wait_state_; }
+
+ static void OnNotification(uintptr_t context_value,
+ MojoResult result,
+ MojoHandleSignalsState state,
+ MojoWatcherNotificationFlags flags) {
+ auto* context = reinterpret_cast<Context*>(context_value);
+ context->Notify(result, state);
+ if (result == MOJO_RESULT_CANCELLED)
+ context->Release();
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<Context>;
+
+ ~Context() {}
+
+ void Notify(MojoResult result, MojoHandleSignalsState state) {
+ if (wait_result_ == MOJO_RESULT_UNKNOWN) {
+ wait_result_ = result;
+ wait_state_ = state;
+ }
+ event_.Signal();
+ }
+
+ base::WaitableEvent event_;
+ MojoResult wait_result_ = MOJO_RESULT_UNKNOWN;
+ MojoHandleSignalsState wait_state_ = {0, 0};
+
+ DISALLOW_COPY_AND_ASSIGN(Context);
+ };
+
+ scoped_refptr<Context> context_;
+
+ DISALLOW_COPY_AND_ASSIGN(Waiter);
+};
+
+} // namespace
#if defined(OS_MACOSX) && !defined(OS_IOS)
namespace {
@@ -130,9 +230,7 @@
MojoHandle mp,
MojoHandle* handles,
uint32_t expected_num_handles) {
- CHECK_EQ(MojoWait(mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
- nullptr),
- MOJO_RESULT_OK);
+ CHECK_EQ(WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE), MOJO_RESULT_OK);
uint32_t message_size = 0;
uint32_t num_handles = 0;
@@ -154,9 +252,7 @@
// static
std::string MojoTestBase::ReadMessageWithOptionalHandle(MojoHandle mp,
MojoHandle* handle) {
- CHECK_EQ(MojoWait(mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
- nullptr),
- MOJO_RESULT_OK);
+ CHECK_EQ(WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE), MOJO_RESULT_OK);
uint32_t message_size = 0;
uint32_t num_handles = 0;
@@ -191,9 +287,7 @@
void MojoTestBase::ReadMessage(MojoHandle mp,
char* data,
size_t num_bytes) {
- CHECK_EQ(MojoWait(mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
- nullptr),
- MOJO_RESULT_OK);
+ CHECK_EQ(WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE), MOJO_RESULT_OK);
uint32_t message_size = 0;
uint32_t num_handles = 0;
@@ -288,8 +382,7 @@
// static
void MojoTestBase::WriteData(MojoHandle producer, const std::string& data) {
- CHECK_EQ(MojoWait(producer, MOJO_HANDLE_SIGNAL_WRITABLE,
- MOJO_DEADLINE_INDEFINITE, nullptr),
+ CHECK_EQ(WaitForSignals(producer, MOJO_HANDLE_SIGNAL_WRITABLE),
MOJO_RESULT_OK);
uint32_t num_bytes = static_cast<uint32_t>(data.size());
CHECK_EQ(MojoWriteData(producer, data.data(), &num_bytes,
@@ -300,8 +393,7 @@
// static
std::string MojoTestBase::ReadData(MojoHandle consumer, size_t size) {
- CHECK_EQ(MojoWait(consumer, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, nullptr),
+ CHECK_EQ(WaitForSignals(consumer, MOJO_HANDLE_SIGNAL_READABLE),
MOJO_RESULT_OK);
std::vector<char> buffer(size);
uint32_t num_bytes = static_cast<uint32_t>(size);
@@ -313,6 +405,21 @@
return std::string(buffer.data(), buffer.size());
}
+// static
+MojoHandleSignalsState MojoTestBase::GetSignalsState(MojoHandle handle) {
+ MojoHandleSignalsState signals_state;
+ CHECK_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(handle, &signals_state));
+ return signals_state;
+}
+
+// static
+MojoResult MojoTestBase::WaitForSignals(MojoHandle handle,
+ MojoHandleSignals signals,
+ MojoHandleSignalsState* state) {
+ Waiter waiter;
+ return waiter.Wait(handle, signals, state);
+}
+
} // namespace test
} // namespace edk
} // namespace mojo
diff --git a/mojo/edk/test/mojo_test_base.h b/mojo/edk/test/mojo_test_base.h
index fa5b64c..35e2c2b 100644
--- a/mojo/edk/test/mojo_test_base.h
+++ b/mojo/edk/test/mojo_test_base.h
@@ -30,8 +30,6 @@
~MojoTestBase() override;
using LaunchType = MultiprocessTestHelper::LaunchType;
-
- protected:
using HandlerCallback = base::Callback<void(ScopedMessagePipeHandle)>;
class ClientController {
@@ -152,6 +150,14 @@
// Reads data from a data pipe.
static std::string ReadData(MojoHandle consumer, size_t size);
+ // Queries the signals state of |handle|.
+ static MojoHandleSignalsState GetSignalsState(MojoHandle handle);
+
+ // Helper to block the calling thread waiting for signals to be raised.
+ static MojoResult WaitForSignals(MojoHandle handle,
+ MojoHandleSignals signals,
+ MojoHandleSignalsState* state = nullptr);
+
void set_launch_type(LaunchType launch_type) { launch_type_ = launch_type; }
private:
diff --git a/mojo/public/c/system/functions.h b/mojo/public/c/system/functions.h
index 750a29e..4dad70b 100644
--- a/mojo/public/c/system/functions.h
+++ b/mojo/public/c/system/functions.h
@@ -46,6 +46,21 @@
// fail with |MOJO_RESULT_INVALID_ARGUMENT| if they happen after.
MOJO_SYSTEM_EXPORT MojoResult MojoClose(MojoHandle handle);
+// Queries the last known signals state of a handle.
+//
+// Note that no guarantees can be made about the accuracy of the returned
+// signals state by the time this returns, as other threads in the system may
+// change the handle's state at any time. Use with appropriate discretion.
+//
+// Returns:
+// |MOJO_RESULT_OK| on success. |*signals_state| is populated with the
+// last known signals state of |handle|.
+// |MOJO_RESULT_INVALID_ARGUMENT| if |handle| is not a valid handle or
+// |signals_state| is null.
+MOJO_SYSTEM_EXPORT MojoResult
+MojoQueryHandleSignalsState(MojoHandle handle,
+ struct MojoHandleSignalsState* signals_state);
+
// Waits on the given handle until one of the following happens:
// - A signal indicated by |signals| is satisfied.
// - It becomes known that no signal indicated by |signals| will ever be
diff --git a/mojo/public/c/system/tests/core_unittest.cc b/mojo/public/c/system/tests/core_unittest.cc
index 8a54380..ada99d4 100644
--- a/mojo/public/c/system/tests/core_unittest.cc
+++ b/mojo/public/c/system/tests/core_unittest.cc
@@ -41,9 +41,9 @@
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(MOJO_HANDLE_INVALID));
// Wait:
- EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
- MojoWait(MOJO_HANDLE_INVALID, ~MOJO_HANDLE_SIGNAL_NONE, 1000000,
- nullptr));
+ EXPECT_EQ(
+ MOJO_RESULT_INVALID_ARGUMENT,
+ MojoWait(MOJO_HANDLE_INVALID, ~MOJO_HANDLE_SIGNAL_NONE, 0, nullptr));
h0 = MOJO_HANDLE_INVALID;
sig = ~MOJO_HANDLE_SIGNAL_NONE;
@@ -98,16 +98,9 @@
EXPECT_NE(h0, MOJO_HANDLE_INVALID);
EXPECT_NE(h1, MOJO_HANDLE_INVALID);
- // Shouldn't be readable, we haven't written anything.
+ // Shouldn't be readable, we haven't written anything. Should be writable.
MojoHandleSignalsState state;
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
- MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE, 0, &state));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals);
- EXPECT_EQ(kSignalAll, state.satisfiable_signals);
-
- // Should be writable.
- EXPECT_EQ(MOJO_RESULT_OK,
- MojoWait(h0, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &state));
+ EXPECT_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(h0, &state));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals);
EXPECT_EQ(kSignalAll, state.satisfiable_signals);
@@ -147,9 +140,7 @@
EXPECT_STREQ(kHello, buffer);
// |h0| should no longer be readable.
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
- MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE, 10, &state));
-
+ EXPECT_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(h0, &state));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals);
EXPECT_EQ(kSignalAll, state.satisfiable_signals);
@@ -164,7 +155,7 @@
EXPECT_EQ(
MOJO_RESULT_FAILED_PRECONDITION,
MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
- 1000, &state));
+ MOJO_DEADLINE_INDEFINITE, &state));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals);
@@ -188,18 +179,14 @@
// The consumer |hc| shouldn't be readable.
MojoHandleSignalsState state;
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
- MojoWait(hc, MOJO_HANDLE_SIGNAL_READABLE, 0, &state));
-
+ EXPECT_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(hc, &state));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
state.satisfiable_signals);
// The producer |hp| should be writable.
- EXPECT_EQ(MOJO_RESULT_OK,
- MojoWait(hp, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &state));
-
+ EXPECT_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(hp, &state));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
state.satisfiable_signals);
@@ -276,7 +263,8 @@
// |hc| should no longer be readable.
EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- MojoWait(hc, MOJO_HANDLE_SIGNAL_READABLE, 1000, &state));
+ MojoWait(hc, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
+ &state));
EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals);
EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals);
diff --git a/mojo/public/c/system/tests/core_unittest_pure_c.c b/mojo/public/c/system/tests/core_unittest_pure_c.c
index fa3caa5..890bcfa 100644
--- a/mojo/public/c/system/tests/core_unittest_pure_c.c
+++ b/mojo/public/c/system/tests/core_unittest_pure_c.c
@@ -54,6 +54,9 @@
EXPECT_NE(MOJO_RESULT_OK, MojoClose(handle0));
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+ MojoQueryHandleSignalsState(handle0, NULL));
+
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
MojoWait(handle0, ~MOJO_HANDLE_SIGNAL_NONE,
MOJO_DEADLINE_INDEFINITE, NULL));
diff --git a/mojo/public/c/system/thunks.cc b/mojo/public/c/system/thunks.cc
index 1e92954..877ab8f 100644
--- a/mojo/public/c/system/thunks.cc
+++ b/mojo/public/c/system/thunks.cc
@@ -22,6 +22,13 @@
return g_thunks.Close(handle);
}
+MojoResult MojoQueryHandleSignalsState(
+ MojoHandle handle,
+ struct MojoHandleSignalsState* signals_state) {
+ assert(g_thunks.QueryHandleSignalsState);
+ return g_thunks.QueryHandleSignalsState(handle, signals_state);
+}
+
MojoResult MojoWait(MojoHandle handle,
MojoHandleSignals signals,
MojoDeadline deadline,
diff --git a/mojo/public/c/system/thunks.h b/mojo/public/c/system/thunks.h
index 31d2289..70417b8 100644
--- a/mojo/public/c/system/thunks.h
+++ b/mojo/public/c/system/thunks.h
@@ -22,6 +22,9 @@
size_t size; // Should be set to sizeof(MojoSystemThunks).
MojoTimeTicks (*GetTimeTicksNow)();
MojoResult (*Close)(MojoHandle handle);
+ MojoResult (*QueryHandleSignalsState)(
+ MojoHandle handle,
+ struct MojoHandleSignalsState* signals_state);
MojoResult (*Wait)(MojoHandle handle,
MojoHandleSignals signals,
MojoDeadline deadline,
diff --git a/mojo/public/cpp/system/handle.h b/mojo/public/cpp/system/handle.h
index 5b2eb7b..3f949e7 100644
--- a/mojo/public/cpp/system/handle.h
+++ b/mojo/public/cpp/system/handle.h
@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "mojo/public/c/system/functions.h"
#include "mojo/public/c/system/types.h"
+#include "mojo/public/cpp/system/handle_signals_state.h"
namespace mojo {
@@ -170,6 +171,14 @@
DCHECK_EQ(MOJO_RESULT_OK, result);
}
+ HandleSignalsState QuerySignalsState() const {
+ HandleSignalsState signals_state;
+ MojoResult result = MojoQueryHandleSignalsState(
+ value_, static_cast<MojoHandleSignalsState*>(&signals_state));
+ DCHECK_EQ(MOJO_RESULT_OK, result);
+ return signals_state;
+ }
+
private:
MojoHandle value_;
diff --git a/mojo/public/cpp/system/handle_signals_state.h b/mojo/public/cpp/system/handle_signals_state.h
new file mode 100644
index 0000000..9e2430f
--- /dev/null
+++ b/mojo/public/cpp/system/handle_signals_state.h
@@ -0,0 +1,83 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_PUBLIC_CPP_SYSTEM_HANDLE_SIGNALS_STATE_H_
+#define MOJO_PUBLIC_CPP_SYSTEM_HANDLE_SIGNALS_STATE_H_
+
+#include "mojo/public/c/system/types.h"
+#include "mojo/public/cpp/system/system_export.h"
+
+namespace mojo {
+
+// A convenience wrapper around the MojoHandleSignalsState struct.
+struct MOJO_CPP_SYSTEM_EXPORT HandleSignalsState final
+ : public MojoHandleSignalsState {
+ HandleSignalsState() {
+ satisfied_signals = MOJO_HANDLE_SIGNAL_NONE;
+ satisfiable_signals = MOJO_HANDLE_SIGNAL_NONE;
+ }
+
+ HandleSignalsState(MojoHandleSignals satisfied,
+ MojoHandleSignals satisfiable) {
+ satisfied_signals = satisfied;
+ satisfiable_signals = satisfiable;
+ }
+
+ bool operator==(const HandleSignalsState& other) const {
+ return satisfied_signals == other.satisfied_signals &&
+ satisfiable_signals == other.satisfiable_signals;
+ }
+
+ // TODO(rockot): Remove this in favor of operator==.
+ bool equals(const HandleSignalsState& other) const {
+ return satisfied_signals == other.satisfied_signals &&
+ satisfiable_signals == other.satisfiable_signals;
+ }
+
+ bool satisfies(MojoHandleSignals signals) const {
+ return !!(satisfied_signals & signals);
+ }
+
+ bool can_satisfy(MojoHandleSignals signals) const {
+ return !!(satisfiable_signals & signals);
+ }
+
+ // The handle is currently readable. May apply to a message pipe handle or
+ // data pipe consumer handle.
+ bool readable() const { return satisfies(MOJO_HANDLE_SIGNAL_READABLE); }
+
+ // The handle is currently writable. May apply to a message pipe handle or
+ // data pipe producer handle.
+ bool writable() const { return satisfies(MOJO_HANDLE_SIGNAL_WRITABLE); }
+
+ // The handle's peer is closed. May apply to any message pipe or data pipe
+ // handle.
+ bool peer_closed() const { return satisfies(MOJO_HANDLE_SIGNAL_PEER_CLOSED); }
+
+ // The handle will never be |readable()| again.
+ bool never_readable() const {
+ return !can_satisfy(MOJO_HANDLE_SIGNAL_READABLE);
+ }
+
+ // The handle will never be |writable()| again.
+ bool never_writable() const {
+ return !can_satisfy(MOJO_HANDLE_SIGNAL_WRITABLE);
+ }
+
+ // The handle can never indicate |peer_closed()|. Never true for message pipe
+ // or data pipe handles (they can always signal peer closure), but always true
+ // for other types of handles (they have no peer.)
+ bool never_peer_closed() const {
+ return !can_satisfy(MOJO_HANDLE_SIGNAL_PEER_CLOSED);
+ }
+
+ // (Copy and assignment allowed.)
+};
+
+static_assert(sizeof(HandleSignalsState) == sizeof(MojoHandleSignalsState),
+ "HandleSignalsState should add no overhead");
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_SYSTEM_HANDLE_SIGNALS_STATE_H_
diff --git a/mojo/public/cpp/system/tests/handle_signals_state_unittest.cc b/mojo/public/cpp/system/tests/handle_signals_state_unittest.cc
new file mode 100644
index 0000000..82f538e
--- /dev/null
+++ b/mojo/public/cpp/system/tests/handle_signals_state_unittest.cc
@@ -0,0 +1,42 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/public/cpp/system/handle_signals_state.h"
+
+#include "mojo/public/c/system/types.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace {
+
+using HandleSignalsStateTest = testing::Test;
+
+TEST_F(HandleSignalsStateTest, SanityCheck) {
+ // There's not much to test here. Just a quick sanity check to make sure the
+ // code compiles and the helper methods do what they're supposed to do.
+
+ HandleSignalsState empty_signals(MOJO_HANDLE_SIGNAL_NONE,
+ MOJO_HANDLE_SIGNAL_NONE);
+ EXPECT_FALSE(empty_signals.readable());
+ EXPECT_FALSE(empty_signals.writable());
+ EXPECT_FALSE(empty_signals.peer_closed());
+ EXPECT_TRUE(empty_signals.never_readable());
+ EXPECT_TRUE(empty_signals.never_writable());
+ EXPECT_TRUE(empty_signals.never_peer_closed());
+
+ HandleSignalsState all_signals(
+ MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE |
+ MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+ MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE |
+ MOJO_HANDLE_SIGNAL_PEER_CLOSED);
+ EXPECT_TRUE(all_signals.readable());
+ EXPECT_TRUE(all_signals.writable());
+ EXPECT_TRUE(all_signals.peer_closed());
+ EXPECT_FALSE(all_signals.never_readable());
+ EXPECT_FALSE(all_signals.never_writable());
+ EXPECT_FALSE(all_signals.never_peer_closed());
+}
+
+} // namespace
+} // namespace mojo
diff --git a/mojo/public/java/system/src/org/chromium/mojo/system/Core.java b/mojo/public/java/system/src/org/chromium/mojo/system/Core.java
index e5c6d08..40e4be3 100644
--- a/mojo/public/java/system/src/org/chromium/mojo/system/Core.java
+++ b/mojo/public/java/system/src/org/chromium/mojo/system/Core.java
@@ -4,8 +4,6 @@
package org.chromium.mojo.system;
-import java.util.List;
-
/**
* Core mojo interface giving access to the base operations. See |src/mojo/public/c/system/core.h|
* for the underlying api.
@@ -129,142 +127,6 @@
}
/**
- * Result for the |wait| method.
- */
- public static class WaitResult {
- /**
- * The result of the wait method.
- * <p>
- * |MojoResult.OK| if some signal in |signals| was satisfied (or is already satisfied).
- * <p>
- * |MojoResult.DEADLINE_EXCEEDED| if the deadline has passed without any of the signals
- * being satisfied.
- * <p>
- * |MojoResult.CANCELLED| if |handle| is closed concurrently by another thread.
- * <p>
- * |MojoResult.FAILED_PRECONDITION| if it is or becomes impossible that any flag in
- * |signals| will ever be satisfied (for example, if the other endpoint is closed).
- */
- private int mMojoResult;
-
- /**
- * The signaling state of handles.
- */
- private HandleSignalsState mHandleSignalsState;
-
- /**
- * Returns the mojoResult.
- */
- public int getMojoResult() {
- return mMojoResult;
- }
-
- /**
- * @param mojoResult the mojoResult to set
- */
- public void setMojoResult(int mojoResult) {
- mMojoResult = mojoResult;
- }
-
- /**
- * Returns the handleSignalsState.
- */
- public HandleSignalsState getHandleSignalsState() {
- return mHandleSignalsState;
- }
-
- /**
- * @param handleSignalsState the handleSignalsState to set
- */
- public void setHandleSignalsState(HandleSignalsState handleSignalsState) {
- mHandleSignalsState = handleSignalsState;
- }
- }
-
- /**
- * Waits on the given |handle| until the state indicated by |signals| is satisfied or until
- * |deadline| has passed.
- *
- * @return a |WaitResult|.
- */
- public WaitResult wait(Handle handle, HandleSignals signals, long deadline);
-
- /**
- * Result for the |waitMany| method.
- */
- public static class WaitManyResult {
-
- /**
- * See |wait| for the different possible values.
- */
- private int mMojoResult;
-
- /**
- * If |mojoResult| is |MojoResult.OK|, |handleIndex| is the index of the handle for which
- * some flag was satisfied (or is already satisfied). If |mojoResult| is
- * |MojoResult.CANCELLED| or |MojoResult.FAILED_PRECONDITION|, |handleIndex| is the index of
- * the handle for which the issue occurred.
- */
- private int mHandleIndex;
-
- /**
- * The signaling state of handles. Will not be set if |mojoResult| is
- * |MOJO_RESULT_INVALID_ARGUMENT| or |MOJO_RESULT_RESOURCE_EXHAUSTED|
- */
- private List<HandleSignalsState> mSignalStates;
-
- /**
- * Returns the mojoResult.
- */
- public int getMojoResult() {
- return mMojoResult;
- }
-
- /**
- * @param mojoResult the mojoResult to set
- */
- public void setMojoResult(int mojoResult) {
- mMojoResult = mojoResult;
- }
-
- /**
- * Returns the handleIndex.
- */
- public int getHandleIndex() {
- return mHandleIndex;
- }
-
- /**
- * @param handleIndex the handleIndex to set
- */
- public void setHandleIndex(int handleIndex) {
- mHandleIndex = handleIndex;
- }
-
- /**
- * Returns the signalStates.
- */
- public List<HandleSignalsState> getSignalStates() {
- return mSignalStates;
- }
-
- /**
- * @param signalStates the signalStates to set
- */
- public void setSignalStates(List<HandleSignalsState> signalStates) {
- mSignalStates = signalStates;
- }
- }
-
- /**
- * Waits on handle in |handles| for at least one of them to satisfy the associated
- * |HandleSignals|, or until |deadline| has passed.
- *
- * @returns a |WaitManyResult|.
- */
- public WaitManyResult waitMany(List<Pair<Handle, HandleSignals>> handles, long deadline);
-
- /**
* Creates a message pipe, which is a bidirectional communication channel for framed data (i.e.,
* messages), with the given options. Messages can contain plain data and/or Mojo handles.
*
diff --git a/mojo/public/java/system/src/org/chromium/mojo/system/Handle.java b/mojo/public/java/system/src/org/chromium/mojo/system/Handle.java
index 6181669..903f36d 100644
--- a/mojo/public/java/system/src/org/chromium/mojo/system/Handle.java
+++ b/mojo/public/java/system/src/org/chromium/mojo/system/Handle.java
@@ -4,7 +4,7 @@
package org.chromium.mojo.system;
-import org.chromium.mojo.system.Core.WaitResult;
+import org.chromium.mojo.system.Core.HandleSignalsState;
import java.io.Closeable;
@@ -25,9 +25,9 @@
public void close();
/**
- * @see Core#wait(Handle, Core.HandleSignals, long)
+ * @return the last known signaling state of the handle.
*/
- public WaitResult wait(Core.HandleSignals signals, long deadline);
+ public HandleSignalsState querySignalsState();
/**
* @return whether the handle is valid. A handle is valid until it has been explicitly closed or
diff --git a/mojo/public/java/system/src/org/chromium/mojo/system/InvalidHandle.java b/mojo/public/java/system/src/org/chromium/mojo/system/InvalidHandle.java
index 9c20fdd..f8b99c6 100644
--- a/mojo/public/java/system/src/org/chromium/mojo/system/InvalidHandle.java
+++ b/mojo/public/java/system/src/org/chromium/mojo/system/InvalidHandle.java
@@ -4,8 +4,7 @@
package org.chromium.mojo.system;
-import org.chromium.mojo.system.Core.HandleSignals;
-import org.chromium.mojo.system.Core.WaitResult;
+import org.chromium.mojo.system.Core.HandleSignalsState;
import org.chromium.mojo.system.DataPipe.ConsumerHandle;
import org.chromium.mojo.system.DataPipe.ProducerHandle;
@@ -38,10 +37,10 @@
}
/**
- * @see Handle#wait(Core.HandleSignals, long)
+ * @see Handle#querySignalsState()
*/
@Override
- public WaitResult wait(HandleSignals signals, long deadline) {
+ public HandleSignalsState querySignalsState() {
throw new MojoException(MojoResult.INVALID_ARGUMENT);
}
diff --git a/mojo/public/js/core.js b/mojo/public/js/core.js
index ef480ee..28fdcb7 100644
--- a/mojo/public/js/core.js
+++ b/mojo/public/js/core.js
@@ -142,6 +142,18 @@
function close(handle) { [native code] }
/**
+ * Queries the last known signaling state of |handle|.
+ *
+ * @param {MojoHandle} handle Handle to query.
+ * @return {object} An object of the form {
+ * result, // MOJO_RESULT_OK or MOJO_RESULT_INVALID_ARGUMENT
+ * satisfiedSignals, // MojoHandleSignals (see above)
+ * satisfiableSignals, // MojoHandleSignals
+ * }
+ */
+function queryHandleSignalsState(handle) { [native code] }
+
+/**
* Waits on the given handle until a signal indicated by |signals| is
* satisfied or until |deadline| is passed. See MojoWait for more information.
*
diff --git a/mojo/public/js/tests/core_unittest.js b/mojo/public/js/tests/core_unittest.js
index 395ed05..7c77713 100644
--- a/mojo/public/js/tests/core_unittest.js
+++ b/mojo/public/js/tests/core_unittest.js
@@ -89,35 +89,15 @@
}
function testReadAndWriteMessage(pipe) {
- var wait = core.waitMany([], [], 0);
- expect(wait.result).toBe(core.RESULT_INVALID_ARGUMENT);
- expect(wait.index).toBe(null);
- expect(wait.signalsState).toBe(null);
+ var state0 = core.queryHandleSignalsState(pipe.handle0);
+ expect(state0.result).toBe(core.RESULT_OK);
+ expect(state0.satisfiedSignals).toBe(core.HANDLE_SIGNAL_WRITABLE);
+ expect(state0.satisfiableSignals).toBe(HANDLE_SIGNAL_ALL);
- wait = core.wait(pipe.handle0, core.HANDLE_SIGNAL_READABLE, 0);
- expect(wait.result).toBe(core.RESULT_DEADLINE_EXCEEDED);
- expect(wait.signalsState.satisfiedSignals).toBe(
- core.HANDLE_SIGNAL_WRITABLE);
- expect(wait.signalsState.satisfiableSignals).toBe(HANDLE_SIGNAL_ALL);
-
- wait = core.waitMany(
- [pipe.handle0, pipe.handle1],
- [core.HANDLE_SIGNAL_READABLE,core.HANDLE_SIGNAL_READABLE],
- 0);
- expect(wait.result).toBe(core.RESULT_DEADLINE_EXCEEDED);
- expect(wait.index).toBe(null);
- expect(wait.signalsState[0].satisfiedSignals).toBe(
- core.HANDLE_SIGNAL_WRITABLE);
- expect(wait.signalsState[0].satisfiableSignals).toBe(HANDLE_SIGNAL_ALL);
- expect(wait.signalsState[1].satisfiedSignals).toBe(
- core.HANDLE_SIGNAL_WRITABLE);
- expect(wait.signalsState[1].satisfiableSignals).toBe(HANDLE_SIGNAL_ALL);
-
- wait = core.wait(pipe.handle0, core.HANDLE_SIGNAL_WRITABLE, 0);
- expect(wait.result).toBe(core.RESULT_OK);
- expect(wait.signalsState.satisfiedSignals).toBe(
- core.HANDLE_SIGNAL_WRITABLE);
- expect(wait.signalsState.satisfiableSignals).toBe(HANDLE_SIGNAL_ALL);
+ var state1 = core.queryHandleSignalsState(pipe.handle1);
+ expect(state1.result).toBe(core.RESULT_OK);
+ expect(state1.satisfiedSignals).toBe(core.HANDLE_SIGNAL_WRITABLE);
+ expect(state1.satisfiableSignals).toBe(HANDLE_SIGNAL_ALL);
var senderData = new Uint8Array(42);
for (var i = 0; i < senderData.length; ++i) {
@@ -130,14 +110,13 @@
expect(result).toBe(core.RESULT_OK);
- wait = core.wait(pipe.handle0, core.HANDLE_SIGNAL_WRITABLE, 0);
- expect(wait.result).toBe(core.RESULT_OK);
- expect(wait.signalsState.satisfiedSignals).toBe(
- core.HANDLE_SIGNAL_WRITABLE);
- expect(wait.signalsState.satisfiableSignals).toBe(HANDLE_SIGNAL_ALL);
+ state0 = core.queryHandleSignalsState(pipe.handle0);
+ expect(state0.result).toBe(core.RESULT_OK);
+ expect(state0.satisfiedSignals).toBe(core.HANDLE_SIGNAL_WRITABLE);
+ expect(state0.satisfiableSignals).toBe(HANDLE_SIGNAL_ALL);
- wait = core.wait(pipe.handle1, core.HANDLE_SIGNAL_READABLE,
- core.DEADLINE_INDEFINITE);
+ var wait = core.wait(pipe.handle1, core.HANDLE_SIGNAL_READABLE,
+ core.DEADLINE_INDEFINITE);
expect(wait.result).toBe(core.RESULT_OK);
expect(wait.signalsState.satisfiedSignals).toBe(HANDLE_SIGNAL_READWRITABLE);
expect(wait.signalsState.satisfiableSignals).toBe(HANDLE_SIGNAL_ALL);