summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuis Hector Chavez <lhchavez@google.com>2018-07-20 09:39:22 -0700
committerLuis Hector Chavez <lhchavez@google.com>2018-10-04 12:33:00 -0700
commit23b27ba5c54bf6368980117d91bc51c4495e2c50 (patch)
tree320ad17250cb91835d7b705e582a89f841c49b7e
parent5f1197afff4d4303a93ada7786c8eb572b78ae6e (diff)
downloadlibchrome-master-cuttlefish-testing-release.tar.gz
This change adds Interface.Manager.buildThreadSafeProxy(), which is roughly analogous to mojo::ThreadSafeInterfacePtr<T>. Given that Java does not have move-only semantics, the Proxy object that is passed is unbound and a new object is returned. Bug: None Test: cheets_ContainerSmokeTest in Chrome OS Change-Id: I6565f9e526e3fa8f8cb222cb8cd11e95bb57f7d3 Reviewed-on: https://chromium-review.googlesource.com/1147320 Reviewed-by: Ken Rockot <rockot@chromium.org> Commit-Queue: Luis Hector Chavez <lhchavez@chromium.org> Cr-Commit-Position: refs/heads/master@{#577429}
-rw-r--r--libchrome_tools/patch/mojo-Add-a-way-to-create-thread-safe-interfaces-in-Java.patch137
-rw-r--r--mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java88
2 files changed, 225 insertions, 0 deletions
diff --git a/libchrome_tools/patch/mojo-Add-a-way-to-create-thread-safe-interfaces-in-Java.patch b/libchrome_tools/patch/mojo-Add-a-way-to-create-thread-safe-interfaces-in-Java.patch
new file mode 100644
index 0000000000..7610293924
--- /dev/null
+++ b/libchrome_tools/patch/mojo-Add-a-way-to-create-thread-safe-interfaces-in-Java.patch
@@ -0,0 +1,137 @@
+From 225f21f660b943ff9ade13b0d114e8ba3b3036d5 Mon Sep 17 00:00:00 2001
+From: Luis Hector Chavez <lhchavez@google.com>
+Date: Fri, 20 Jul 2018 09:39:22 -0700
+Subject: [PATCH] Mojo: Add a way to create thread-safe interfaces in Java
+
+This change adds Interface.Manager.buildThreadSafeProxy(), which is
+roughly analogous to mojo::ThreadSafeInterfacePtr<T>. Given that Java
+does not have move-only semantics, the Proxy object that is passed is
+unbound and a new object is returned.
+
+Bug: 810084
+Test: cheets_ContainerSmokeTest in Chrome OS
+Change-Id: I6565f9e526e3fa8f8cb222cb8cd11e95bb57f7d3
+Reviewed-on: https://chromium-review.googlesource.com/1147320
+Reviewed-by: Ken Rockot <rockot@chromium.org>
+Commit-Queue: Luis Hector Chavez <lhchavez@chromium.org>
+Cr-Commit-Position: refs/heads/master@{#577429}
+---
+ .../org/chromium/mojo/bindings/Interface.java | 88 +++++++++++++++++++
+ 1 file changed, 88 insertions(+)
+
+diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java
+index e3be8b3..f7d3f80 100644
+--- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java
++++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java
+@@ -20,6 +20,7 @@ import org.chromium.mojo.system.MojoException;
+ import org.chromium.mojo.system.Pair;
+
+ import java.io.Closeable;
++import java.util.concurrent.Executor;
+
+ /**
+ * Base class for mojo generated interfaces.
+@@ -317,6 +318,67 @@ public interface Interface extends ConnectionErrorHandler, Closeable {
+
+ }
+
++ /**
++ * A {@link MessageReceiverWithResponder} implementation that forwards all calls to the thread
++ * the ThreadSafeForwarder was created.
++ */
++ class ThreadSafeForwarder implements MessageReceiverWithResponder {
++
++ /**
++ * The {@link MessageReceiverWithResponder} that will receive a serialized message for
++ * each method call.
++ */
++ private final MessageReceiverWithResponder mMessageReceiver;
++
++ /**
++ * The {@link Executor} to forward all tasks to.
++ */
++ private final Executor mExecutor;
++
++ /**
++ * Constructor.
++ *
++ * @param core the Core implementation used to create pipes and access the async waiter.
++ * @param messageReceiver the message receiver to send message to.
++ */
++ public ThreadSafeForwarder(Core core, MessageReceiverWithResponder messageReceiver) {
++ mMessageReceiver = messageReceiver;
++ mExecutor = ExecutorFactory.getExecutorForCurrentThread(core);
++ }
++
++ /**
++ * @see org.chromium.mojo.bindings.MessageReceiver#close()
++ */
++ @Override
++ public void close() {
++ mExecutor.execute(() -> {
++ mMessageReceiver.close();
++ });
++ }
++
++ /**
++ * @see org.chromium.mojo.bindings.MessageReceiver#accept()
++ */
++ @Override
++ public boolean accept(Message message) {
++ mExecutor.execute(() -> {
++ mMessageReceiver.accept(message);
++ });
++ return true;
++ }
++
++ /**
++ * @see org.chromium.mojo.bindings.MessageReceiverWithResponder#acceptWithResponder()
++ */
++ @Override
++ public boolean acceptWithResponder(Message message, MessageReceiver responder) {
++ mExecutor.execute(() -> {
++ mMessageReceiver.acceptWithResponder(message, responder);
++ });
++ return true;
++ }
++ }
++
+ /**
+ * The |Manager| object enables building of proxies and stubs for a given interface.
+ *
+@@ -385,6 +447,32 @@ public interface Interface extends ConnectionErrorHandler, Closeable {
+ return new InterfaceRequest<I>(handle);
+ }
+
++ /**
++ * Constructs a thread-safe Proxy forwarding the calls to the given message receiver.
++ * All calls can be performed from any thread and are posted to the {@link Executor} that
++ * is associated with the thread on which this method was called on.
++ *
++ * The original Proxy object is unbound.
++ */
++ public final P buildThreadSafeProxy(P proxy) {
++ HandlerImpl handlerImpl = (HandlerImpl) proxy.getProxyHandler();
++ Core core = handlerImpl.getCore();
++ int version = handlerImpl.getVersion();
++
++ Router router = new RouterImpl(handlerImpl.passHandle());
++ // Close the original proxy now that its handle has been passed.
++ proxy.close();
++
++ proxy = buildProxy(
++ core, new ThreadSafeForwarder(core, new AutoCloseableRouter(core, router)));
++ DelegatingConnectionErrorHandler handlers = new DelegatingConnectionErrorHandler();
++ handlers.addConnectionErrorHandler(proxy);
++ router.setErrorHandler(handlers);
++ router.start();
++ ((HandlerImpl) proxy.getProxyHandler()).setVersion(version);
++ return proxy;
++ }
++
+ /**
+ * Binds the implementation to the given |router|.
+ */
+--
+2.19.0.605.g01d371f741-goog
+
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java
index e3be8b3daa..f7d3f80256 100644
--- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java
+++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java
@@ -20,6 +20,7 @@ import org.chromium.mojo.system.MojoException;
import org.chromium.mojo.system.Pair;
import java.io.Closeable;
+import java.util.concurrent.Executor;
/**
* Base class for mojo generated interfaces.
@@ -318,6 +319,67 @@ public interface Interface extends ConnectionErrorHandler, Closeable {
}
/**
+ * A {@link MessageReceiverWithResponder} implementation that forwards all calls to the thread
+ * the ThreadSafeForwarder was created.
+ */
+ class ThreadSafeForwarder implements MessageReceiverWithResponder {
+
+ /**
+ * The {@link MessageReceiverWithResponder} that will receive a serialized message for
+ * each method call.
+ */
+ private final MessageReceiverWithResponder mMessageReceiver;
+
+ /**
+ * The {@link Executor} to forward all tasks to.
+ */
+ private final Executor mExecutor;
+
+ /**
+ * Constructor.
+ *
+ * @param core the Core implementation used to create pipes and access the async waiter.
+ * @param messageReceiver the message receiver to send message to.
+ */
+ public ThreadSafeForwarder(Core core, MessageReceiverWithResponder messageReceiver) {
+ mMessageReceiver = messageReceiver;
+ mExecutor = ExecutorFactory.getExecutorForCurrentThread(core);
+ }
+
+ /**
+ * @see org.chromium.mojo.bindings.MessageReceiver#close()
+ */
+ @Override
+ public void close() {
+ mExecutor.execute(() -> {
+ mMessageReceiver.close();
+ });
+ }
+
+ /**
+ * @see org.chromium.mojo.bindings.MessageReceiver#accept()
+ */
+ @Override
+ public boolean accept(Message message) {
+ mExecutor.execute(() -> {
+ mMessageReceiver.accept(message);
+ });
+ return true;
+ }
+
+ /**
+ * @see org.chromium.mojo.bindings.MessageReceiverWithResponder#acceptWithResponder()
+ */
+ @Override
+ public boolean acceptWithResponder(Message message, MessageReceiver responder) {
+ mExecutor.execute(() -> {
+ mMessageReceiver.acceptWithResponder(message, responder);
+ });
+ return true;
+ }
+ }
+
+ /**
* The |Manager| object enables building of proxies and stubs for a given interface.
*
* @param <I> the type of the interface the manager can handle.
@@ -386,6 +448,32 @@ public interface Interface extends ConnectionErrorHandler, Closeable {
}
/**
+ * Constructs a thread-safe Proxy forwarding the calls to the given message receiver.
+ * All calls can be performed from any thread and are posted to the {@link Executor} that
+ * is associated with the thread on which this method was called on.
+ *
+ * The original Proxy object is unbound.
+ */
+ public final P buildThreadSafeProxy(P proxy) {
+ HandlerImpl handlerImpl = (HandlerImpl) proxy.getProxyHandler();
+ Core core = handlerImpl.getCore();
+ int version = handlerImpl.getVersion();
+
+ Router router = new RouterImpl(handlerImpl.passHandle());
+ // Close the original proxy now that its handle has been passed.
+ proxy.close();
+
+ proxy = buildProxy(
+ core, new ThreadSafeForwarder(core, new AutoCloseableRouter(core, router)));
+ DelegatingConnectionErrorHandler handlers = new DelegatingConnectionErrorHandler();
+ handlers.addConnectionErrorHandler(proxy);
+ router.setErrorHandler(handlers);
+ router.start();
+ ((HandlerImpl) proxy.getProxyHandler()).setVersion(version);
+ return proxy;
+ }
+
+ /**
* Binds the implementation to the given |router|.
*/
final void bind(Core core, I impl, Router router) {