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

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

Issue 2438903002: Fuchsia: Use mx_handle_wait_many in the eventhandler (Closed)
Patch Set: Add logging 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 handles_ = static_cast<mx_handle_t*>(
37 malloc(kInitialCapacity * sizeof(*handles_)));
38 signals_ = static_cast<mx_signals_t*>(
39 malloc(kInitialCapacity * sizeof(*signals_)));
40 signals_states_ = static_cast<mx_signals_state_t*>(
41 malloc(kInitialCapacity * sizeof(*signals_states_)));
siva 2016/10/21 20:21:50 ASSERT/FATAL for NULL value returns from these mal
zra 2016/10/21 20:37:41 Done.
42 }
43
44
45 MagentaWaitManyInfo::~MagentaWaitManyInfo() {
46 free(descriptor_infos_);
47 free(handles_);
48 free(signals_);
49 free(signals_states_);
50 }
51
52
53 void MagentaWaitManyInfo::AddHandle(mx_handle_t handle,
54 mx_signals_t signals,
55 DescriptorInfo* di) {
56 #if defined(DEBUG)
57 // Check that the handle is not already in the list.
58 for (intptr_t i = 0; i < size_; i++) {
59 if (handles_[i] == handle) {
60 FATAL("The handle is already in the list!");
61 }
62 }
63 #endif
64 intptr_t new_size = size_ + 1;
65 GrowArraysIfNeeded(new_size);
66 descriptor_infos_[size_] = di;
67 handles_[size_] = handle;
68 signals_[size_] = signals;
69 signals_states_[size_].satisfied = MX_SIGNAL_NONE;
70 signals_states_[size_].satisfiable = MX_SIGNAL_NONE;
71 size_ = new_size;
72 LOG_INFO("AddHandle(%ld, %ld, %p), size = %ld\n", handle, signals, di, size_);
73 }
74
75
76 void MagentaWaitManyInfo::RemoveHandle(mx_handle_t handle) {
77 intptr_t idx;
78 for (idx = 1; idx < size_; idx++) {
79 if (handle == handles_[idx]) {
80 break;
81 }
82 }
83 if (idx == size_) {
84 FATAL("Handle is not in the list!");
85 }
86
87 if (idx != (size_ - 1)) {
88 descriptor_infos_[idx] = descriptor_infos_[size_ - 1];
89 handles_[idx] = handles_[size_ - 1];
90 signals_[idx] = signals_[size_ - 1];
91 signals_states_[idx] = signals_states_[size_ - 1];
92 }
93 descriptor_infos_[size_ - 1] = NULL;
94 handles_[size_ - 1] = MX_HANDLE_INVALID;
95 signals_[size_ - 1] = MX_SIGNAL_NONE;
96 signals_states_[size_ - 1].satisfied = MX_SIGNAL_NONE;
97 signals_states_[size_ - 1].satisfiable = MX_SIGNAL_NONE;
98 size_ = size_ - 1;
99 LOG_INFO("RemoveHandle(%ld), size = %ld\n", handle, size_);
100 }
101
102
103 void MagentaWaitManyInfo::GrowArraysIfNeeded(intptr_t desired_size) {
104 if (desired_size < capacity_) {
105 return;
106 }
107 intptr_t new_capacity = desired_size + (desired_size >> 1);
108 descriptor_infos_ = static_cast<DescriptorInfo**>(
109 realloc(descriptor_infos_, new_capacity * sizeof(*descriptor_infos_)));
110 handles_ = static_cast<mx_handle_t*>(
111 realloc(handles_, new_capacity * sizeof(*handles_)));
112 signals_ = static_cast<mx_signals_t*>(
113 realloc(signals_, new_capacity * sizeof(*signals_)));
114 signals_states_ = static_cast<mx_signals_state_t*>(
115 realloc(signals_states_, new_capacity * sizeof(*signals_states_)));
siva 2016/10/21 20:21:50 Should we assert or fatal out if these realloc cal
zra 2016/10/21 20:37:41 Done.
116 capacity_ = new_capacity;
117 LOG_INFO("GrowArraysIfNeeded(%ld), capacity = %ld\n",
118 desired_size, capacity_);
119 }
120
121
22 EventHandlerImplementation::EventHandlerImplementation() { 122 EventHandlerImplementation::EventHandlerImplementation() {
23 mx_status_t status = mx_msgpipe_create(interrupt_handles_, 0); 123 mx_status_t status = mx_msgpipe_create(interrupt_handles_, 0);
24 if (status != NO_ERROR) { 124 if (status != NO_ERROR) {
25 FATAL1("mx_msgpipe_create failed: %s\n", mx_status_get_string(status)); 125 FATAL1("mx_msgpipe_create failed: %s\n", mx_status_get_string(status));
26 } 126 }
27 shutdown_ = false; 127 shutdown_ = false;
128 info_.AddHandle(interrupt_handles_[0],
129 MX_SIGNAL_READABLE | MX_SIGNAL_PEER_CLOSED,
130 NULL);
131 LOG_INFO("EventHandlerImplementation initialized\n");
28 } 132 }
29 133
30 134
31 EventHandlerImplementation::~EventHandlerImplementation() { 135 EventHandlerImplementation::~EventHandlerImplementation() {
32 mx_status_t status = mx_handle_close(interrupt_handles_[0]); 136 mx_status_t status = mx_handle_close(interrupt_handles_[0]);
33 if (status != NO_ERROR) { 137 if (status != NO_ERROR) {
34 FATAL1("mx_handle_close failed: %s\n", mx_status_get_string(status)); 138 FATAL1("mx_handle_close failed: %s\n", mx_status_get_string(status));
35 } 139 }
36 status = mx_handle_close(interrupt_handles_[1]); 140 status = mx_handle_close(interrupt_handles_[1]);
37 if (status != NO_ERROR) { 141 if (status != NO_ERROR) {
38 FATAL1("mx_handle_close failed: %s\n", mx_status_get_string(status)); 142 FATAL1("mx_handle_close failed: %s\n", mx_status_get_string(status));
39 } 143 }
144 LOG_INFO("EventHandlerImplementation destroyed\n");
40 } 145 }
41 146
42 147
43 void EventHandlerImplementation::WakeupHandler(intptr_t id, 148 void EventHandlerImplementation::WakeupHandler(intptr_t id,
44 Dart_Port dart_port, 149 Dart_Port dart_port,
45 int64_t data) { 150 int64_t data) {
46 InterruptMessage msg; 151 InterruptMessage msg;
47 msg.id = id; 152 msg.id = id;
48 msg.dart_port = dart_port; 153 msg.dart_port = dart_port;
49 msg.data = data; 154 msg.data = data;
50 155
51 mx_status_t status = 156 mx_status_t status =
52 mx_msgpipe_write(interrupt_handles_[1], &msg, sizeof(msg), NULL, 0, 0); 157 mx_msgpipe_write(interrupt_handles_[1], &msg, sizeof(msg), NULL, 0, 0);
53 if (status != NO_ERROR) { 158 if (status != NO_ERROR) {
54 FATAL1("mx_msgpipe_write failed: %s\n", mx_status_get_string(status)); 159 FATAL1("mx_msgpipe_write failed: %s\n", mx_status_get_string(status));
55 } 160 }
161 LOG_INFO("WakeupHandler(%ld, %ld, %lld)\n", id, dart_port, data);
56 } 162 }
57 163
58 164
59 void EventHandlerImplementation::HandleInterruptFd() { 165 void EventHandlerImplementation::HandleInterruptFd() {
166 LOG_INFO("HandleInterruptFd entry\n");
60 InterruptMessage msg; 167 InterruptMessage msg;
61 uint32_t bytes = kInterruptMessageSize; 168 uint32_t bytes = kInterruptMessageSize;
62 mx_status_t status; 169 mx_status_t status;
63 while (true) { 170 while (true) {
64 status = mx_msgpipe_read( 171 status = mx_msgpipe_read(
65 interrupt_handles_[0], &msg, &bytes, NULL, NULL, 0); 172 interrupt_handles_[0], &msg, &bytes, NULL, NULL, 0);
66 if (status != NO_ERROR) { 173 if (status != NO_ERROR) {
67 break; 174 break;
68 } 175 }
69 ASSERT(bytes == kInterruptMessageSize); 176 ASSERT(bytes == kInterruptMessageSize);
70 if (msg.id == kTimerId) { 177 if (msg.id == kTimerId) {
178 LOG_INFO("HandleInterruptFd read timer update\n");
71 timeout_queue_.UpdateTimeout(msg.dart_port, msg.data); 179 timeout_queue_.UpdateTimeout(msg.dart_port, msg.data);
72 } else if (msg.id == kShutdownId) { 180 } else if (msg.id == kShutdownId) {
181 LOG_INFO("HandleInterruptFd read shutdown\n");
73 shutdown_ = true; 182 shutdown_ = true;
74 } else { 183 } else {
184 // TODO(zra): Handle commands to add and remove handles from the
185 // MagentaWaitManyInfo.
75 UNIMPLEMENTED(); 186 UNIMPLEMENTED();
76 } 187 }
77 } 188 }
78 // status == ERR_SHOULD_WAIT when we try to read and there are no messages 189 // 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. 190 // available, so it is an error if we get here and status != ERR_SHOULD_WAIT.
80 if (status != ERR_SHOULD_WAIT) { 191 if (status != ERR_SHOULD_WAIT) {
81 FATAL1("mx_msgpipe_read failed: %s\n", mx_status_get_string(status)); 192 FATAL1("mx_msgpipe_read failed: %s\n", mx_status_get_string(status));
82 } 193 }
194 LOG_INFO("HandleInterruptFd exit\n");
195 }
196
197
198 void EventHandlerImplementation::HandleEvents() {
199 LOG_INFO("HandleEvents entry\n");
200 for (intptr_t i = 1; i < info_.size(); i++) {
201 if (info_.signals_states()[i].satisfied != MX_SIGNAL_NONE) {
202 // Only the control handle has no descriptor info.
203 ASSERT(info_.descriptor_infos()[i] != NULL);
204 ASSERT(info_.handles()[i] != interrupt_handles_[0]);
205 // TODO(zra): Handle events on other handles. At the moment we are
206 // only interrupted when there is a message on interrupt_handles_[0].
207 UNIMPLEMENTED();
208 }
209 }
210
211 if ((info_.signals_states()[0].satisfied & MX_SIGNAL_PEER_CLOSED) != 0) {
212 FATAL("EventHandlerImplementation::Poll: Unexpected peer closed\n");
213 }
214 if ((info_.signals_states()[0].satisfied & MX_SIGNAL_READABLE) != 0) {
215 LOG_INFO("HandleEvents interrupt_handles_[0] readable\n");
216 HandleInterruptFd();
217 } else {
218 LOG_INFO("HandleEvents interrupt_handles_[0] not readable\n");
219 }
83 } 220 }
84 221
85 222
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 { 223 int64_t EventHandlerImplementation::GetTimeout() const {
94 if (!timeout_queue_.HasTimeout()) { 224 if (!timeout_queue_.HasTimeout()) {
95 return kInfinityTimeout; 225 return kInfinityTimeout;
96 } 226 }
97 int64_t millis = timeout_queue_.CurrentTimeout() - 227 int64_t millis = timeout_queue_.CurrentTimeout() -
98 TimerUtils::GetCurrentMonotonicMillis(); 228 TimerUtils::GetCurrentMonotonicMillis();
99 return (millis < 0) ? 0 : millis; 229 return (millis < 0) ? 0 : millis;
100 } 230 }
101 231
102 232
(...skipping 10 matching lines...) Expand all
113 243
114 244
115 void EventHandlerImplementation::Poll(uword args) { 245 void EventHandlerImplementation::Poll(uword args) {
116 EventHandler* handler = reinterpret_cast<EventHandler*>(args); 246 EventHandler* handler = reinterpret_cast<EventHandler*>(args);
117 EventHandlerImplementation* handler_impl = &handler->delegate_; 247 EventHandlerImplementation* handler_impl = &handler->delegate_;
118 ASSERT(handler_impl != NULL); 248 ASSERT(handler_impl != NULL);
119 249
120 while (!handler_impl->shutdown_) { 250 while (!handler_impl->shutdown_) {
121 int64_t millis = handler_impl->GetTimeout(); 251 int64_t millis = handler_impl->GetTimeout();
122 ASSERT((millis == kInfinityTimeout) || (millis >= 0)); 252 ASSERT((millis == kInfinityTimeout) || (millis >= 0));
123
124 mx_time_t timeout = 253 mx_time_t timeout =
125 millis * kMicrosecondsPerMillisecond * kNanosecondsPerMicrosecond; 254 millis * kMicrosecondsPerMillisecond * kNanosecondsPerMicrosecond;
126 mx_signals_state_t signals_state; 255 const MagentaWaitManyInfo& info = handler_impl->info();
127 mx_status_t status = mx_handle_wait_one( 256 uint32_t result_index;
128 handler_impl->interrupt_handles_[0], 257 LOG_INFO("mx_handle_wait_many(%ld, %p, %p, %lld, %p, %p)\n",
129 MX_SIGNAL_READABLE | MX_SIGNAL_PEER_CLOSED, 258 info.size(), info.handles(), info.signals(), timeout, &result_index,
259 info.signals_states());
260 mx_status_t status = mx_handle_wait_many(
261 info.size(),
262 info.handles(),
263 info.signals(),
130 timeout, 264 timeout,
131 &signals_state); 265 &result_index,
266 info.signals_states());
132 if ((status != NO_ERROR) && (status != ERR_TIMED_OUT)) { 267 if ((status != NO_ERROR) && (status != ERR_TIMED_OUT)) {
133 FATAL1("mx_handle_wait_one failed: %s\n", mx_status_get_string(status)); 268 FATAL1("mx_handle_wait_many failed: %s\n", mx_status_get_string(status));
134 } else { 269 } else {
270 LOG_INFO("mx_handle_wait_many returned: %ld\n", status);
135 handler_impl->HandleTimeout(); 271 handler_impl->HandleTimeout();
136 if ((signals_state.satisfied & MX_SIGNAL_READABLE) != 0) { 272 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 } 273 }
143 } 274 }
144 handler->NotifyShutdownDone(); 275 handler->NotifyShutdownDone();
276 LOG_INFO("EventHandlerImplementation notifying about shutdown\n");
145 } 277 }
146 278
147 279
148 void EventHandlerImplementation::Start(EventHandler* handler) { 280 void EventHandlerImplementation::Start(EventHandler* handler) {
149 int result = Thread::Start(&EventHandlerImplementation::Poll, 281 int result = Thread::Start(&EventHandlerImplementation::Poll,
150 reinterpret_cast<uword>(handler)); 282 reinterpret_cast<uword>(handler));
151 if (result != 0) { 283 if (result != 0) {
152 FATAL1("Failed to start event handler thread %d", result); 284 FATAL1("Failed to start event handler thread %d", result);
153 } 285 }
154 } 286 }
155 287
156 288
157 void EventHandlerImplementation::Shutdown() { 289 void EventHandlerImplementation::Shutdown() {
158 SendData(kShutdownId, 0, 0); 290 SendData(kShutdownId, 0, 0);
159 } 291 }
160 292
161 293
162 void EventHandlerImplementation::SendData(intptr_t id, 294 void EventHandlerImplementation::SendData(intptr_t id,
163 Dart_Port dart_port, 295 Dart_Port dart_port,
164 int64_t data) { 296 int64_t data) {
165 WakeupHandler(id, dart_port, data); 297 WakeupHandler(id, dart_port, data);
166 } 298 }
167 299
168 } // namespace bin 300 } // namespace bin
169 } // namespace dart 301 } // namespace dart
170 302
171 #endif // defined(TARGET_OS_FUCHSIA) 303 #endif // defined(TARGET_OS_FUCHSIA)
172 304
173 #endif // !defined(DART_IO_DISABLED) 305 #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