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

Side by Side Diff: mojo/public/platform/dart/dart_handle_watcher.h

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 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 unified diff | Download patch
« no previous file with comments | « mojo/public/platform/dart/README.md ('k') | mojo/public/platform/dart/dart_handle_watcher.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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_PLATFORM_DART_DART_HANDLE_WATCHER_H_
6 #define MOJO_PUBLIC_PLATFORM_DART_DART_HANDLE_WATCHER_H_
7
8 #include <mojo/result.h>
9 #include <mojo/system/handle.h>
10
11 #include <mutex>
12 #include <thread>
13 #include <unordered_map>
14
15 #include "dart/runtime/include/dart_api.h"
16
17 #include "mojo/public/cpp/environment/logging.h"
18 #include "mojo/public/cpp/system/macros.h"
19
20 namespace mojo {
21 namespace dart {
22
23 #define MOJO_HANDLE_SIGNAL_ALL (MOJO_HANDLE_SIGNAL_READABLE | \
24 MOJO_HANDLE_SIGNAL_WRITABLE | \
25 MOJO_HANDLE_SIGNAL_PEER_CLOSED)
26
27 // HandleWatcherCommands are sent to HandleWatchers.
28 class HandleWatcherCommand {
29 public:
30 enum Command {
31 kCommandAddHandle = 0,
32 kCommandRemoveHandle = 1,
33 kCommandCloseHandle = 2,
34 kCommandAddTimer = 3,
35 kCommandShutdownHandleWatcher = 4,
36 };
37
38 // Construct a command to listen for |handle| to have |signals| and ping
39 // |port| when this happens.
40 static HandleWatcherCommand Add(MojoHandle handle,
41 MojoHandleSignals signals,
42 Dart_Port port) {
43 HandleWatcherCommand result;
44 result.handle_or_deadline_ = static_cast<int64_t>(handle);
45 result.port_ = port;
46 result.set_data(kCommandAddHandle, signals);
47 return result;
48 }
49
50 // Construct a command to stop listening for |handle|.
51 static HandleWatcherCommand Remove(MojoHandle handle) {
52 HandleWatcherCommand result;
53 result.handle_or_deadline_ = static_cast<int64_t>(handle);
54 result.port_ = ILLEGAL_PORT;
55 result.set_data(kCommandRemoveHandle, MOJO_HANDLE_SIGNAL_NONE);
56 return result;
57 }
58
59 // Construct a command to close |handle| and ping |port| when done.
60 static HandleWatcherCommand Close(MojoHandle handle,
61 Dart_Port port) {
62 HandleWatcherCommand result;
63 result.handle_or_deadline_ = static_cast<int64_t>(handle);
64 result.port_ = port;
65 result.set_data(kCommandCloseHandle, MOJO_HANDLE_SIGNAL_NONE);
66 return result;
67 }
68
69 // Construct a command to ping |port| when it is |deadline|.
70 static HandleWatcherCommand Timer(int64_t deadline,
71 Dart_Port port) {
72 HandleWatcherCommand result;
73 result.handle_or_deadline_ = deadline;
74 result.port_ = port;
75 result.set_data(kCommandAddTimer, MOJO_HANDLE_SIGNAL_NONE);
76 return result;
77 }
78
79 // Construct a command to shutdown the handle watcher thread.
80 static HandleWatcherCommand Shutdown() {
81 HandleWatcherCommand result;
82 result.handle_or_deadline_ = MOJO_HANDLE_INVALID;
83 result.port_ = ILLEGAL_PORT;
84 result.set_data(kCommandShutdownHandleWatcher, MOJO_HANDLE_SIGNAL_NONE);
85 return result;
86 }
87
88 // Construct an empty command.
89 static HandleWatcherCommand Empty() {
90 HandleWatcherCommand result;
91 return result;
92 }
93
94 // Construct a command sent from Dart code.
95 static HandleWatcherCommand FromDart(int64_t command,
96 int64_t handle_or_deadline,
97 Dart_Port port,
98 int64_t signals) {
99 switch (command) {
100 case kCommandAddHandle:
101 return Add(handle_or_deadline, signals, port);
102 break;
103 case kCommandRemoveHandle:
104 return Remove(handle_or_deadline);
105 break;
106 case kCommandCloseHandle:
107 return Close(handle_or_deadline, port);
108 break;
109 case kCommandAddTimer:
110 return Timer(handle_or_deadline, port);
111 break;
112 case kCommandShutdownHandleWatcher:
113 return Shutdown();
114 break;
115 default:
116 // Unreachable.
117 MOJO_CHECK(false);
118 return Empty();
119 }
120 }
121
122 // Get the command.
123 Command command() const {
124 return static_cast<Command>((data_ >> 3));
125 }
126
127 // Get the signals associated with the command.
128 MojoHandleSignals signals() const {
129 return data_ & MOJO_HANDLE_SIGNAL_ALL;
130 }
131
132 // Get the handle associated with the command.
133 MojoHandle handle() const {
134 return static_cast<MojoHandle>(handle_or_deadline_);
135 }
136
137 // Get the deadline associated with the command.
138 int64_t deadline() const {
139 return handle_or_deadline_;
140 }
141
142 // Get the port associated with the command.
143 Dart_Port port() const {
144 return port_;
145 }
146
147 private:
148 HandleWatcherCommand() {
149 handle_or_deadline_ = 0;
150 port_ = ILLEGAL_PORT;
151 data_ = 0;
152 }
153
154 void set_data(Command command, MojoHandleSignals signals) {
155 MOJO_CHECK(MOJO_HANDLE_SIGNAL_ALL < (1 << 3));
156 data_ = (command << 3) | (signals & MOJO_HANDLE_SIGNAL_ALL);
157 }
158
159 int64_t handle_or_deadline_;
160 Dart_Port port_;
161 int64_t data_;
162 };
163
164
165 // A Dart HandleWatcher can be started by calling |HandleWatcher::Start|.
166 // Each |Start| call creates a message pipe for communicating with the
167 // handle watcher and spawns a thread where the handle watcher waits for
168 // events on handles.
169 //
170 // NOTE: If multiple handle watchers are needed, |Start| can be safely called
171 // multiple times because all state is held inside the spawned thread.
172 class HandleWatcher {
173 public:
174 // Starts a new HandleWatcher thread and returns the message pipe handle
175 // that is used to communicate with the handle watcher. Returns
176 // the handle that should be passed to |SendCommand|.
177 static MojoHandle Start();
178
179 // Encode a |command| for the handle watcher and write it to
180 // |control_pipe_producer_handle|.
181 static MojoResult SendCommand(MojoHandle control_pipe_producer_handle,
182 const HandleWatcherCommand& command);
183
184 // Stops and joins the handle watcher thread at the other end of the
185 // given pipe handle.
186 static void Stop(MojoHandle control_pipe_consumer_handle);
187
188 // Stops and joins all handle watcher threads.
189 static void StopAll();
190
191 private:
192 static void ThreadMain(MojoHandle control_pipe_consumer_handle);
193
194 // Remove the mapping for |handle| from |handle_watcher_threads_| and return
195 // the associated thread object. Assumes |handle_watcher_threads_mutex_| is
196 // held.
197 static std::thread* RemoveLocked(MojoHandle handle);
198
199 // Remove the mapping for |handle| from |handle_watcher_threads_| and join
200 // the associated thread. Assumes |handle_watcher_threads_mutex_| is held.
201 static void StopLocked(MojoHandle handle);
202
203 // A mapping from control handle to handle watcher thread.
204 static std::unordered_map<MojoHandle, std::thread*> handle_watcher_threads_;
205
206 // Protects |handle_watcher_threads_|
207 static std::mutex handle_watcher_threads_mutex_;
208
209 MOJO_DISALLOW_COPY_AND_ASSIGN(HandleWatcher);
210 };
211
212
213 } // namespace dart
214 } // namespace mojo
215
216 #endif // MOJO_PUBLIC_PLATFORM_DART_DART_HANDLE_WATCHER_H_
OLDNEW
« no previous file with comments | « mojo/public/platform/dart/README.md ('k') | mojo/public/platform/dart/dart_handle_watcher.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698