OLD | NEW |
---|---|
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 Loading... | |
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) |
OLD | NEW |