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

Side by Side Diff: mojo/public/cpp/bindings/thread_safe_interface_ptr.h

Issue 2498743002: Mojo: introducing a thread safe interface pointer. (Closed)
Patch Set: Clean-up Created 4 years, 1 month 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_
7
8 namespace mojo {
9
10 #include <memory>
11
12 #include "base/callback.h"
13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/task_runner.h"
16 #include "base/threading/thread_task_runner_handle.h"
17 #include "mojo/public/cpp/bindings/message.h"
18
19 namespace internal {
20 template <typename Interface, bool use_multiplex_router>
21 class InterfacePtrState;
22 }
23
24 // ThreadSafeInterfacePtr is a version of InterfacePtr that lets caller invoke
25 // interface methods from any threads. Callbacks are called on the thread that
26 // made the interface call.
27 // To create a ThreadSafeInterfacePtr, create a regular InterfacePtr and then
28 // retrieve a ThreadSafeInterfacePtr with InterfacePtr::GetThreadSafePtr() (this
29 // must be done on one thread). You can then use the ThreadSafeInterfacePtr from
30 // any thread.
yzshen1 2016/11/11 22:32:10 Please consider adding comments about whether the
Jay Civelli 2016/11/15 05:02:30 Updated that comment based on the modified design
31 template <typename Interface>
32 class ThreadSafeInterfacePtr : public MessageReceiverWithResponder,
33 public base::RefCountedThreadSafe<ThreadSafeInterfacePtr<Interface>> {
darin (slow to review) 2016/11/12 04:09:23 Does this class need to be ref-counted? Can it be
Jay Civelli 2016/11/15 05:02:30 After discussing with @yzshen1 we think it makes m
34 public:
35 using ProxyType = typename Interface::Proxy_;
36
37 using AcceptCallback = base::Callback<void(Message)>;
38 using AcceptWithResponderCallback =
39 base::Callback<void(Message, std::unique_ptr<MessageReceiver>)>;
40
41 Interface* get_interface() { return &proxy_; }
yzshen1 2016/11/11 22:32:10 Does it make sense to name it "get()" to be more c
Jay Civelli 2016/11/15 05:02:30 Very good point. Done.
42
43 private:
44 friend class base::RefCountedThreadSafe<ThreadSafeInterfacePtr<Interface>>;
45 friend class internal::InterfacePtrState<Interface, true>;
46
47 ThreadSafeInterfacePtr(
48 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
49 const AcceptCallback& accept_callback,
50 const AcceptWithResponderCallback& accept_with_responder_callback)
51 : task_runner_(task_runner),
52 proxy_(this),
53 accept_callback_(accept_callback),
54 accept_with_responder_callback_(accept_with_responder_callback) {
55 }
56
57 // MessageReceiverWithResponder implementation:
58 bool Accept(Message* message) override {
59 task_runner_->PostTask(
60 FROM_HERE,
61 base::Bind(accept_callback_, base::Passed(std::move(*message))));
62 return true;
63 }
64
65 bool AcceptWithResponder(Message* message,
66 MessageReceiver* responder) override {
67 auto forward_responder = base::MakeUnique<ForwardToCallingThread>(
68 base::WrapUnique(responder));
69 task_runner_->PostTask(
70 FROM_HERE,
71 base::Bind(accept_with_responder_callback_,
72 base::Passed(std::move(*message)),
73 base::Passed(std::move(forward_responder))));
74 return true;
75 }
76
77 class ForwardToCallingThread : public MessageReceiver {
78 public:
79 explicit ForwardToCallingThread(std::unique_ptr<MessageReceiver> responder)
80 : responder_(std::move(responder)),
81 task_runner_(base::ThreadTaskRunnerHandle::Get()) {
82 }
83
84 private:
85 bool Accept(Message* message) {
86 // The current instance will be deleted when this method returns, so we
87 // have to relinquish the responder so it does not get deleted.
88 task_runner_->PostTask(FROM_HERE,
89 base::Bind(&ForwardToCallingThread::CallAcceptAndDeleteResponder,
90 base::Passed(std::move(responder_)),
91 base::Passed(std::move(*message))));
92 return true;
93 }
94
95 static void CallAcceptAndDeleteResponder(
96 std::unique_ptr<MessageReceiver> responder,
97 Message message) {
98 ignore_result(responder->Accept(&message));
99 }
100
101 std::unique_ptr<MessageReceiver> responder_;
102 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
103 };
104
105 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
106 ProxyType proxy_;
107 AcceptCallback accept_callback_;
108 AcceptWithResponderCallback accept_with_responder_callback_;
109 };
110
111 } // namespace mojo
112
113 #endif // MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698