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

Side by Side Diff: runtime/bin/eventhandler_fuchsia.cc

Issue 2438903002: Fuchsia: Use mx_handle_wait_many in the eventhandler (Closed)
Patch Set: Add NULL checks Created 4 years, 2 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 | « runtime/bin/eventhandler_fuchsia.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #if !defined(DART_IO_DISABLED) 5 #if !defined(DART_IO_DISABLED)
6 6
7 #include "platform/globals.h" 7 #include "platform/globals.h"
8 #if defined(TARGET_OS_FUCHSIA) 8 #if defined(TARGET_OS_FUCHSIA)
9 9
10 #include "bin/eventhandler.h" 10 #include "bin/eventhandler.h"
11 #include "bin/eventhandler_fuchsia.h" 11 #include "bin/eventhandler_fuchsia.h"
12 12
13 #include <magenta/status.h> 13 #include <magenta/status.h>
14 #include <magenta/syscalls.h> 14 #include <magenta/syscalls.h>
15 15
16 #include "bin/log.h"
16 #include "bin/thread.h" 17 #include "bin/thread.h"
17 #include "bin/utils.h" 18 #include "bin/utils.h"
18 19
20 #if defined(EVENTHANDLER_LOGGING)
21 #define LOG_ERR(msg, ...) Log::PrintErr(msg, ##__VA_ARGS__)
22 #define LOG_INFO(msg, ...) Log::Print(msg, ##__VA_ARGS__)
23 #else
24 #define LOG_ERR(msg, ...)
25 #define LOG_INFO(msg, ...)
26 #endif // defined(EVENTHANDLER_LOGGING)
27
19 namespace dart { 28 namespace dart {
20 namespace bin { 29 namespace bin {
21 30
31 MagentaWaitManyInfo::MagentaWaitManyInfo()
32 : capacity_(kInitialCapacity),
33 size_(0) {
34 descriptor_infos_ = static_cast<DescriptorInfo**>(
35 malloc(kInitialCapacity * sizeof(*descriptor_infos_)));
36 if (descriptor_infos_ == NULL) {
37 FATAL("Failed to allocate descriptor_infos array");
38 }
39 handles_ = static_cast<mx_handle_t*>(
40 malloc(kInitialCapacity * sizeof(*handles_)));
41 if (handles_ == NULL) {
42 FATAL("Failed to allocate handles array");
43 }
44 signals_ = static_cast<mx_signals_t*>(
45 malloc(kInitialCapacity * sizeof(*signals_)));
46 if (signals_ == NULL) {
47 FATAL("Failed to allocate signals array");
48 }
49 signals_states_ = static_cast<mx_signals_state_t*>(
50 malloc(kInitialCapacity * sizeof(*signals_states_)));
51 if (signals_states_ == NULL) {
52 FATAL("Failed to allocate signals_states array");
53 }
54 }
55
56
57 MagentaWaitManyInfo::~MagentaWaitManyInfo() {
58 free(descriptor_infos_);
59 free(handles_);
60 free(signals_);
61 free(signals_states_);
62 }
63
64
65 void MagentaWaitManyInfo::AddHandle(mx_handle_t handle,
66 mx_signals_t signals,
67 DescriptorInfo* di) {
68 #if defined(DEBUG)
69 // Check that the handle is not already in the list.
70 for (intptr_t i = 0; i < size_; i++) {
71 if (handles_[i] == handle) {
72 FATAL("The handle is already in the list!");
73 }
74 }
75 #endif
76 intptr_t new_size = size_ + 1;
77 GrowArraysIfNeeded(new_size);
78 descriptor_infos_[size_] = di;
79 handles_[size_] = handle;
80 signals_[size_] = signals;
81 signals_states_[size_].satisfied = MX_SIGNAL_NONE;
82 signals_states_[size_].satisfiable = MX_SIGNAL_NONE;
83 size_ = new_size;
84 LOG_INFO("AddHandle(%ld, %ld, %p), size = %ld\n", handle, signals, di, size_);
85 }
86
87
88 void MagentaWaitManyInfo::RemoveHandle(mx_handle_t handle) {
89 intptr_t idx;
90 for (idx = 1; idx < size_; idx++) {
91 if (handle == handles_[idx]) {
92 break;
93 }
94 }
95 if (idx == size_) {
96 FATAL("Handle is not in the list!");
97 }
98
99 if (idx != (size_ - 1)) {
100 descriptor_infos_[idx] = descriptor_infos_[size_ - 1];
101 handles_[idx] = handles_[size_ - 1];
102 signals_[idx] = signals_[size_ - 1];
103 signals_states_[idx] = signals_states_[size_ - 1];
104 }
105 descriptor_infos_[size_ - 1] = NULL;
106 handles_[size_ - 1] = MX_HANDLE_INVALID;
107 signals_[size_ - 1] = MX_SIGNAL_NONE;
108 signals_states_[size_ - 1].satisfied = MX_SIGNAL_NONE;
109 signals_states_[size_ - 1].satisfiable = MX_SIGNAL_NONE;
110 size_ = size_ - 1;
111 LOG_INFO("RemoveHandle(%ld), size = %ld\n", handle, size_);
112 }
113
114
115 void MagentaWaitManyInfo::GrowArraysIfNeeded(intptr_t desired_size) {
116 if (desired_size < capacity_) {
117 return;
118 }
119 intptr_t new_capacity = desired_size + (desired_size >> 1);
120 descriptor_infos_ = static_cast<DescriptorInfo**>(
121 realloc(descriptor_infos_, new_capacity * sizeof(*descriptor_infos_)));
122 if (descriptor_infos_ == NULL) {
123 FATAL("Failed to grow descriptor_infos array");
124 }
125 handles_ = static_cast<mx_handle_t*>(
126 realloc(handles_, new_capacity * sizeof(*handles_)));
127 if (handles_ == NULL) {
128 FATAL("Failed to grow handles array");
129 }
130 signals_ = static_cast<mx_signals_t*>(
131 realloc(signals_, new_capacity * sizeof(*signals_)));
132 if (signals_ == NULL) {
133 FATAL("Failed to grow signals array");
134 }
135 signals_states_ = static_cast<mx_signals_state_t*>(
136 realloc(signals_states_, new_capacity * sizeof(*signals_states_)));
137 if (signals_states_ == NULL) {
138 FATAL("Failed to grow signals_states array");
139 }
140 capacity_ = new_capacity;
141 LOG_INFO("GrowArraysIfNeeded(%ld), capacity = %ld\n",
142 desired_size, capacity_);
143 }
144
145
22 EventHandlerImplementation::EventHandlerImplementation() { 146 EventHandlerImplementation::EventHandlerImplementation() {
23 mx_status_t status = mx_msgpipe_create(interrupt_handles_, 0); 147 mx_status_t status = mx_msgpipe_create(interrupt_handles_, 0);
24 if (status != NO_ERROR) { 148 if (status != NO_ERROR) {
25 FATAL1("mx_msgpipe_create failed: %s\n", mx_status_get_string(status)); 149 FATAL1("mx_msgpipe_create failed: %s\n", mx_status_get_string(status));
26 } 150 }
27 shutdown_ = false; 151 shutdown_ = false;
152 info_.AddHandle(interrupt_handles_[0],
153 MX_SIGNAL_READABLE | MX_SIGNAL_PEER_CLOSED,
154 NULL);
155 LOG_INFO("EventHandlerImplementation initialized\n");
28 } 156 }
29 157
30 158
31 EventHandlerImplementation::~EventHandlerImplementation() { 159 EventHandlerImplementation::~EventHandlerImplementation() {
32 mx_status_t status = mx_handle_close(interrupt_handles_[0]); 160 mx_status_t status = mx_handle_close(interrupt_handles_[0]);
33 if (status != NO_ERROR) { 161 if (status != NO_ERROR) {
34 FATAL1("mx_handle_close failed: %s\n", mx_status_get_string(status)); 162 FATAL1("mx_handle_close failed: %s\n", mx_status_get_string(status));
35 } 163 }
36 status = mx_handle_close(interrupt_handles_[1]); 164 status = mx_handle_close(interrupt_handles_[1]);
37 if (status != NO_ERROR) { 165 if (status != NO_ERROR) {
38 FATAL1("mx_handle_close failed: %s\n", mx_status_get_string(status)); 166 FATAL1("mx_handle_close failed: %s\n", mx_status_get_string(status));
39 } 167 }
168 LOG_INFO("EventHandlerImplementation destroyed\n");
40 } 169 }
41 170
42 171
43 void EventHandlerImplementation::WakeupHandler(intptr_t id, 172 void EventHandlerImplementation::WakeupHandler(intptr_t id,
44 Dart_Port dart_port, 173 Dart_Port dart_port,
45 int64_t data) { 174 int64_t data) {
46 InterruptMessage msg; 175 InterruptMessage msg;
47 msg.id = id; 176 msg.id = id;
48 msg.dart_port = dart_port; 177 msg.dart_port = dart_port;
49 msg.data = data; 178 msg.data = data;
50 179
51 mx_status_t status = 180 mx_status_t status =
52 mx_msgpipe_write(interrupt_handles_[1], &msg, sizeof(msg), NULL, 0, 0); 181 mx_msgpipe_write(interrupt_handles_[1], &msg, sizeof(msg), NULL, 0, 0);
53 if (status != NO_ERROR) { 182 if (status != NO_ERROR) {
54 FATAL1("mx_msgpipe_write failed: %s\n", mx_status_get_string(status)); 183 FATAL1("mx_msgpipe_write failed: %s\n", mx_status_get_string(status));
55 } 184 }
185 LOG_INFO("WakeupHandler(%ld, %ld, %lld)\n", id, dart_port, data);
56 } 186 }
57 187
58 188
59 void EventHandlerImplementation::HandleInterruptFd() { 189 void EventHandlerImplementation::HandleInterruptFd() {
190 LOG_INFO("HandleInterruptFd entry\n");
60 InterruptMessage msg; 191 InterruptMessage msg;
61 uint32_t bytes = kInterruptMessageSize; 192 uint32_t bytes = kInterruptMessageSize;
62 mx_status_t status; 193 mx_status_t status;
63 while (true) { 194 while (true) {
64 status = mx_msgpipe_read( 195 status = mx_msgpipe_read(
65 interrupt_handles_[0], &msg, &bytes, NULL, NULL, 0); 196 interrupt_handles_[0], &msg, &bytes, NULL, NULL, 0);
66 if (status != NO_ERROR) { 197 if (status != NO_ERROR) {
67 break; 198 break;
68 } 199 }
69 ASSERT(bytes == kInterruptMessageSize); 200 ASSERT(bytes == kInterruptMessageSize);
70 if (msg.id == kTimerId) { 201 if (msg.id == kTimerId) {
202 LOG_INFO("HandleInterruptFd read timer update\n");
71 timeout_queue_.UpdateTimeout(msg.dart_port, msg.data); 203 timeout_queue_.UpdateTimeout(msg.dart_port, msg.data);
72 } else if (msg.id == kShutdownId) { 204 } else if (msg.id == kShutdownId) {
205 LOG_INFO("HandleInterruptFd read shutdown\n");
73 shutdown_ = true; 206 shutdown_ = true;
74 } else { 207 } else {
208 // TODO(zra): Handle commands to add and remove handles from the
209 // MagentaWaitManyInfo.
75 UNIMPLEMENTED(); 210 UNIMPLEMENTED();
76 } 211 }
77 } 212 }
78 // status == ERR_SHOULD_WAIT when we try to read and there are no messages 213 // status == ERR_SHOULD_WAIT when we try to read and there are no messages
79 // available, so it is an error if we get here and status != ERR_SHOULD_WAIT. 214 // available, so it is an error if we get here and status != ERR_SHOULD_WAIT.
80 if (status != ERR_SHOULD_WAIT) { 215 if (status != ERR_SHOULD_WAIT) {
81 FATAL1("mx_msgpipe_read failed: %s\n", mx_status_get_string(status)); 216 FATAL1("mx_msgpipe_read failed: %s\n", mx_status_get_string(status));
82 } 217 }
218 LOG_INFO("HandleInterruptFd exit\n");
219 }
220
221
222 void EventHandlerImplementation::HandleEvents() {
223 LOG_INFO("HandleEvents entry\n");
224 for (intptr_t i = 1; i < info_.size(); i++) {
225 if (info_.signals_states()[i].satisfied != MX_SIGNAL_NONE) {
226 // Only the control handle has no descriptor info.
227 ASSERT(info_.descriptor_infos()[i] != NULL);
228 ASSERT(info_.handles()[i] != interrupt_handles_[0]);
229 // TODO(zra): Handle events on other handles. At the moment we are
230 // only interrupted when there is a message on interrupt_handles_[0].
231 UNIMPLEMENTED();
232 }
233 }
234
235 if ((info_.signals_states()[0].satisfied & MX_SIGNAL_PEER_CLOSED) != 0) {
236 FATAL("EventHandlerImplementation::Poll: Unexpected peer closed\n");
237 }
238 if ((info_.signals_states()[0].satisfied & MX_SIGNAL_READABLE) != 0) {
239 LOG_INFO("HandleEvents interrupt_handles_[0] readable\n");
240 HandleInterruptFd();
241 } else {
242 LOG_INFO("HandleEvents interrupt_handles_[0] not readable\n");
243 }
83 } 244 }
84 245
85 246
86 void EventHandlerImplementation::HandleEvents() {
87 // TODO(zra): Handle events from other handles. At the moment we are only
88 // interrupted when there is a message on interrupt_handles_[0].
89 HandleInterruptFd();
90 }
91
92
93 int64_t EventHandlerImplementation::GetTimeout() const { 247 int64_t EventHandlerImplementation::GetTimeout() const {
94 if (!timeout_queue_.HasTimeout()) { 248 if (!timeout_queue_.HasTimeout()) {
95 return kInfinityTimeout; 249 return kInfinityTimeout;
96 } 250 }
97 int64_t millis = timeout_queue_.CurrentTimeout() - 251 int64_t millis = timeout_queue_.CurrentTimeout() -
98 TimerUtils::GetCurrentMonotonicMillis(); 252 TimerUtils::GetCurrentMonotonicMillis();
99 return (millis < 0) ? 0 : millis; 253 return (millis < 0) ? 0 : millis;
100 } 254 }
101 255
102 256
(...skipping 10 matching lines...) Expand all
113 267
114 268
115 void EventHandlerImplementation::Poll(uword args) { 269 void EventHandlerImplementation::Poll(uword args) {
116 EventHandler* handler = reinterpret_cast<EventHandler*>(args); 270 EventHandler* handler = reinterpret_cast<EventHandler*>(args);
117 EventHandlerImplementation* handler_impl = &handler->delegate_; 271 EventHandlerImplementation* handler_impl = &handler->delegate_;
118 ASSERT(handler_impl != NULL); 272 ASSERT(handler_impl != NULL);
119 273
120 while (!handler_impl->shutdown_) { 274 while (!handler_impl->shutdown_) {
121 int64_t millis = handler_impl->GetTimeout(); 275 int64_t millis = handler_impl->GetTimeout();
122 ASSERT((millis == kInfinityTimeout) || (millis >= 0)); 276 ASSERT((millis == kInfinityTimeout) || (millis >= 0));
123
124 mx_time_t timeout = 277 mx_time_t timeout =
125 millis * kMicrosecondsPerMillisecond * kNanosecondsPerMicrosecond; 278 millis * kMicrosecondsPerMillisecond * kNanosecondsPerMicrosecond;
126 mx_signals_state_t signals_state; 279 const MagentaWaitManyInfo& info = handler_impl->info();
127 mx_status_t status = mx_handle_wait_one( 280 uint32_t result_index;
128 handler_impl->interrupt_handles_[0], 281 LOG_INFO("mx_handle_wait_many(%ld, %p, %p, %lld, %p, %p)\n",
129 MX_SIGNAL_READABLE | MX_SIGNAL_PEER_CLOSED, 282 info.size(), info.handles(), info.signals(), timeout, &result_index,
283 info.signals_states());
284 mx_status_t status = mx_handle_wait_many(
285 info.size(),
286 info.handles(),
287 info.signals(),
130 timeout, 288 timeout,
131 &signals_state); 289 &result_index,
290 info.signals_states());
132 if ((status != NO_ERROR) && (status != ERR_TIMED_OUT)) { 291 if ((status != NO_ERROR) && (status != ERR_TIMED_OUT)) {
133 FATAL1("mx_handle_wait_one failed: %s\n", mx_status_get_string(status)); 292 FATAL1("mx_handle_wait_many failed: %s\n", mx_status_get_string(status));
134 } else { 293 } else {
294 LOG_INFO("mx_handle_wait_many returned: %ld\n", status);
135 handler_impl->HandleTimeout(); 295 handler_impl->HandleTimeout();
136 if ((signals_state.satisfied & MX_SIGNAL_READABLE) != 0) { 296 handler_impl->HandleEvents();
137 handler_impl->HandleEvents();
138 }
139 if ((signals_state.satisfied & MX_SIGNAL_PEER_CLOSED) != 0) {
140 FATAL("EventHandlerImplementation::Poll: Unexpected peer closed\n");
141 }
142 } 297 }
143 } 298 }
144 handler->NotifyShutdownDone(); 299 handler->NotifyShutdownDone();
300 LOG_INFO("EventHandlerImplementation notifying about shutdown\n");
145 } 301 }
146 302
147 303
148 void EventHandlerImplementation::Start(EventHandler* handler) { 304 void EventHandlerImplementation::Start(EventHandler* handler) {
149 int result = Thread::Start(&EventHandlerImplementation::Poll, 305 int result = Thread::Start(&EventHandlerImplementation::Poll,
150 reinterpret_cast<uword>(handler)); 306 reinterpret_cast<uword>(handler));
151 if (result != 0) { 307 if (result != 0) {
152 FATAL1("Failed to start event handler thread %d", result); 308 FATAL1("Failed to start event handler thread %d", result);
153 } 309 }
154 } 310 }
155 311
156 312
157 void EventHandlerImplementation::Shutdown() { 313 void EventHandlerImplementation::Shutdown() {
158 SendData(kShutdownId, 0, 0); 314 SendData(kShutdownId, 0, 0);
159 } 315 }
160 316
161 317
162 void EventHandlerImplementation::SendData(intptr_t id, 318 void EventHandlerImplementation::SendData(intptr_t id,
163 Dart_Port dart_port, 319 Dart_Port dart_port,
164 int64_t data) { 320 int64_t data) {
165 WakeupHandler(id, dart_port, data); 321 WakeupHandler(id, dart_port, data);
166 } 322 }
167 323
168 } // namespace bin 324 } // namespace bin
169 } // namespace dart 325 } // namespace dart
170 326
171 #endif // defined(TARGET_OS_FUCHSIA) 327 #endif // defined(TARGET_OS_FUCHSIA)
172 328
173 #endif // !defined(DART_IO_DISABLED) 329 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/eventhandler_fuchsia.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698