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

Unified Diff: mojo/bindings/java/src/org/chromium/mojo/bindings/ExecutorFactory.java

Issue 364063006: JAVA BINDINGS WIP. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updates Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: mojo/bindings/java/src/org/chromium/mojo/bindings/ExecutorFactory.java
diff --git a/mojo/bindings/java/src/org/chromium/mojo/bindings/ExecutorFactory.java b/mojo/bindings/java/src/org/chromium/mojo/bindings/ExecutorFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..0bb269b7d3328b4d9523bafcf5444ca4bce12ef7
--- /dev/null
+++ b/mojo/bindings/java/src/org/chromium/mojo/bindings/ExecutorFactory.java
@@ -0,0 +1,146 @@
+// Copyright 2014 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.
+
+package org.chromium.mojo.bindings;
+
+import org.chromium.mojo.system.AsyncWaiter;
+import org.chromium.mojo.system.AsyncWaiter.Callback;
+import org.chromium.mojo.system.Core;
+import org.chromium.mojo.system.MessagePipeHandle;
+import org.chromium.mojo.system.MessagePipeHandle.ReadMessageResult;
+import org.chromium.mojo.system.MojoException;
+import org.chromium.mojo.system.MojoResult;
+import org.chromium.mojo.system.Pair;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * A factory that allows to access executors that will execute everything on the thread they are
+ * obtained from.
+ */
+class ExecutorFactory {
+ /**
+ * A static buffer used to notify the executor threads.
+ */
+ private static final ByteBuffer NOTIFY_BUFFER = ByteBuffer.allocateDirect(1);
+
+ /**
+ * Implementation of the executor. The executor owned a pair of {@link MessagePipeHandle}. It
+ * waits asynchronously on one handle on the thread it will execute commands. When it receives a
+ * command to execute, it queues it on a queue, and write a message on the other handle.
+ * Whenever a message is received on the first handle, the executor dequeue on action and runs
+ * it.
+ */
+ private static class PipedExecutor implements Executor, Callback {
+
+ /**
+ * The handle to write to.
+ */
+ private final MessagePipeHandle mWriteHandle;
+ /**
+ * The handle to read from.
+ */
+ private final MessagePipeHandle mReadHandle;
+ /**
+ * The list of actions left to be run.
+ */
+ private final List<Runnable> mPendingActions;
+ private final AsyncWaiter mWaiter;
+
+ /**
+ * Constructor.
+ */
+ public PipedExecutor(Core core) {
+ mWaiter = core.getDefaultAsyncWaiter();
+ Pair<MessagePipeHandle, MessagePipeHandle> handles = core.createMessagePipe();
+ mReadHandle = handles.first;
+ mWriteHandle = handles.second;
+ mPendingActions = Collections.synchronizedList(new ArrayList<Runnable>());
+ if (mWaiter != null) {
+ asyncWait();
+ }
+ }
+
+ /**
+ * Wait for the next command to arrive.
+ */
+ private void asyncWait() {
+ mWaiter.asyncWait(mReadHandle, Core.WaitFlags.READABLE, Core.DEADLINE_INFINITE,
+ this);
+ }
+
+ /**
+ * @see Callback#onResult(int)
+ */
+ @Override
+ public void onResult(int result) {
+ if (result == MojoResult.OK) {
+ Runnable toRun = mPendingActions.remove(0);
+ toRun.run();
+ ReadMessageResult readMessageResult = mReadHandle.readMessage(NOTIFY_BUFFER, 0,
+ MessagePipeHandle.ReadFlags.NONE);
+ if (readMessageResult.getMojoResult() == MojoResult.OK) {
+ asyncWait();
+ } else {
+ close();
+ }
+ } else {
+ close();
+ }
+ }
+
+ /**
+ * Close the handles. Should only be called on the executor thread.
+ */
+ void close() {
+ mPendingActions.clear();
+ mReadHandle.close();
+ synchronized (mWriteHandle) {
+ mWriteHandle.close();
+ }
+ }
+
+ /**
+ * @see Callback#onError(MojoException)
+ */
+ @Override
+ public void onError(MojoException exception) {
+ close();
+ }
+
+ /**
+ * @see Executor#execute(Runnable)
+ */
+ @Override
+ public void execute(Runnable command) {
+ mPendingActions.add(command);
+ // Accessing the write handle must be protected, because its internal value will change
+ // when it is closed.
+ synchronized (mWriteHandle) {
+ mWriteHandle.writeMessage(NOTIFY_BUFFER, null, MessagePipeHandle.WriteFlags.NONE);
+ }
+ }
+ }
+
+ /**
+ * Keep one executor per executor thread.
+ */
+ private static final ThreadLocal<Executor> EXECUTORS = new ThreadLocal<Executor>();
+
+ /**
+ * Returns an {@link Executor} that will run all of its actions in the current thread.
+ */
+ public static Executor getExecutorForCurrentThread(Core core) {
+ Executor executor = EXECUTORS.get();
+ if (executor == null) {
+ executor = new PipedExecutor(core);
+ EXECUTORS.set(executor);
+ }
+ return executor;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698