summaryrefslogtreecommitdiff
path: root/libchrome_tools/patch/mojo-Add-a-way-to-create-thread-safe-interfaces-in-Java.patch
blob: 7610293924957396cfe2970c0ceb96d52bf82c9f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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