diff options
author | Luis Hector Chavez <lhchavez@google.com> | 2018-07-20 09:39:22 -0700 |
---|---|---|
committer | Luis Hector Chavez <lhchavez@google.com> | 2018-10-04 12:33:00 -0700 |
commit | 23b27ba5c54bf6368980117d91bc51c4495e2c50 (patch) | |
tree | 320ad17250cb91835d7b705e582a89f841c49b7e /mojo | |
parent | 5f1197afff4d4303a93ada7786c8eb572b78ae6e (diff) | |
download | libchrome-23b27ba5c54bf6368980117d91bc51c4495e2c50.tar.gz |
Mojo: Add a way to create thread-safe interfaces in Javaandroid-o-mr1-iot-release-smart-display-r3oreo-mr1-1.2-iot-releasemaster-cuttlefish-testing-release
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}
Diffstat (limited to 'mojo')
-rw-r--r-- | mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java | 88 |
1 files changed, 88 insertions, 0 deletions
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) { |