OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 #include <errno.h> | 5 #include <errno.h> |
6 #include <poll.h> | 6 #include <poll.h> |
7 #include <pthread.h> | 7 #include <pthread.h> |
8 #include <stdio.h> | 8 #include <stdio.h> |
9 #include <string.h> | 9 #include <string.h> |
10 #include <sys/time.h> | 10 #include <sys/time.h> |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 return events; | 48 return events; |
49 } | 49 } |
50 | 50 |
51 | 51 |
52 EventHandlerImplementation::EventHandlerImplementation() { | 52 EventHandlerImplementation::EventHandlerImplementation() { |
53 intptr_t result; | 53 intptr_t result; |
54 socket_map_size_ = kInitialPortMapSize; | 54 socket_map_size_ = kInitialPortMapSize; |
55 socket_map_ = reinterpret_cast<SocketData*>(calloc(socket_map_size_, | 55 socket_map_ = reinterpret_cast<SocketData*>(calloc(socket_map_size_, |
56 sizeof(SocketData))); | 56 sizeof(SocketData))); |
57 ASSERT(socket_map_ != NULL); | 57 ASSERT(socket_map_ != NULL); |
58 result = pipe(interrupt_fds_); | 58 result = TEMP_FAILURE_RETRY(pipe(interrupt_fds_)); |
59 if (result != 0) { | 59 if (result != 0) { |
60 FATAL("Pipe creation failed"); | 60 FATAL("Pipe creation failed"); |
61 } | 61 } |
62 FDUtils::SetNonBlocking(interrupt_fds_[0]); | 62 FDUtils::SetNonBlocking(interrupt_fds_[0]); |
63 timeout_ = kInfinityTimeout; | 63 timeout_ = kInfinityTimeout; |
64 timeout_port_ = 0; | 64 timeout_port_ = 0; |
65 } | 65 } |
66 | 66 |
67 | 67 |
68 EventHandlerImplementation::~EventHandlerImplementation() { | 68 EventHandlerImplementation::~EventHandlerImplementation() { |
69 free(socket_map_); | 69 free(socket_map_); |
70 close(interrupt_fds_[0]); | 70 TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); |
71 close(interrupt_fds_[1]); | 71 TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); |
72 } | 72 } |
73 | 73 |
74 | 74 |
75 // TODO(hpayer): Use hash table instead of array. | 75 // TODO(hpayer): Use hash table instead of array. |
76 SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd) { | 76 SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd) { |
77 ASSERT(fd >= 0); | 77 ASSERT(fd >= 0); |
78 if (fd >= socket_map_size_) { | 78 if (fd >= socket_map_size_) { |
79 intptr_t new_socket_map_size = socket_map_size_; | 79 intptr_t new_socket_map_size = socket_map_size_; |
80 do { | 80 do { |
81 new_socket_map_size = new_socket_map_size * kPortMapGrowingFactor; | 81 new_socket_map_size = new_socket_map_size * kPortMapGrowingFactor; |
82 } while (fd >= new_socket_map_size); | 82 } while (fd >= new_socket_map_size); |
83 size_t new_socket_map_bytes = new_socket_map_size * sizeof(SocketData); | 83 size_t new_socket_map_bytes = new_socket_map_size * sizeof(SocketData); |
84 socket_map_ = reinterpret_cast<SocketData*>(realloc(socket_map_, | 84 socket_map_ = reinterpret_cast<SocketData*>(realloc(socket_map_, |
85 new_socket_map_bytes)); | 85 new_socket_map_bytes)); |
86 ASSERT(socket_map_ != NULL); | 86 ASSERT(socket_map_ != NULL); |
87 size_t socket_map_bytes = socket_map_size_ * sizeof(SocketData); | 87 size_t socket_map_bytes = socket_map_size_ * sizeof(SocketData); |
88 memset(socket_map_ + socket_map_size_, | 88 memset(socket_map_ + socket_map_size_, |
89 0, | 89 0, |
90 new_socket_map_bytes - socket_map_bytes); | 90 new_socket_map_bytes - socket_map_bytes); |
91 socket_map_size_ = new_socket_map_size; | 91 socket_map_size_ = new_socket_map_size; |
92 } | 92 } |
93 | 93 |
94 SocketData* sd = socket_map_ + fd; | 94 SocketData* sd = socket_map_ + fd; |
95 sd->set_fd(fd); // For now just make sure the fd is set. | 95 sd->set_fd(fd); // For now just make sure the fd is set. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 } | 140 } |
141 } | 141 } |
142 ASSERT(numPollfds == j); | 142 ASSERT(numPollfds == j); |
143 *pollfds_size = j; | 143 *pollfds_size = j; |
144 return pollfds; | 144 return pollfds; |
145 } | 145 } |
146 | 146 |
147 | 147 |
148 bool EventHandlerImplementation::GetInterruptMessage(InterruptMessage* msg) { | 148 bool EventHandlerImplementation::GetInterruptMessage(InterruptMessage* msg) { |
149 int total_read = 0; | 149 int total_read = 0; |
150 int bytes_read = read(interrupt_fds_[0], msg, kInterruptMessageSize); | 150 int bytes_read = |
| 151 TEMP_FAILURE_RETRY(read(interrupt_fds_[0], msg, kInterruptMessageSize)); |
151 if (bytes_read < 0) { | 152 if (bytes_read < 0) { |
152 return false; | 153 return false; |
153 } | 154 } |
154 total_read = bytes_read; | 155 total_read = bytes_read; |
155 while (total_read < kInterruptMessageSize) { | 156 while (total_read < kInterruptMessageSize) { |
156 bytes_read = read(interrupt_fds_[0], | 157 bytes_read = TEMP_FAILURE_RETRY(read(interrupt_fds_[0], |
157 msg + total_read, | 158 msg + total_read, |
158 kInterruptMessageSize - total_read); | 159 kInterruptMessageSize - total_read)); |
159 if (bytes_read > 0) { | 160 if (bytes_read > 0) { |
160 total_read = total_read + bytes_read; | 161 total_read = total_read + bytes_read; |
161 } | 162 } |
162 } | 163 } |
163 return (total_read == kInterruptMessageSize) ? true : false; | 164 return (total_read == kInterruptMessageSize) ? true : false; |
164 } | 165 } |
165 | 166 |
166 void EventHandlerImplementation::HandleInterruptFd() { | 167 void EventHandlerImplementation::HandleInterruptFd() { |
167 InterruptMessage msg; | 168 InterruptMessage msg; |
168 while (GetInterruptMessage(&msg)) { | 169 while (GetInterruptMessage(&msg)) { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 // end-of-file. | 249 // end-of-file. |
249 if (sd->fd() == STDIN_FILENO) { | 250 if (sd->fd() == STDIN_FILENO) { |
250 event_mask = (1 << kCloseEvent); | 251 event_mask = (1 << kCloseEvent); |
251 sd->MarkClosedRead(); | 252 sd->MarkClosedRead(); |
252 } | 253 } |
253 } else { | 254 } else { |
254 // If POLLIN is set with no available data and no POLLHUP use | 255 // If POLLIN is set with no available data and no POLLHUP use |
255 // recv to peek for whether the other end of the socket | 256 // recv to peek for whether the other end of the socket |
256 // actually closed. | 257 // actually closed. |
257 char buffer; | 258 char buffer; |
258 ssize_t bytesPeeked = recv(sd->fd(), &buffer, 1, MSG_PEEK); | 259 ssize_t bytesPeeked = |
| 260 TEMP_FAILURE_RETRY(recv(sd->fd(), &buffer, 1, MSG_PEEK)); |
| 261 ASSERT(EAGAIN == EWOULDBLOCK); |
259 if (bytesPeeked == 0) { | 262 if (bytesPeeked == 0) { |
260 event_mask = (1 << kCloseEvent); | 263 event_mask = (1 << kCloseEvent); |
261 sd->MarkClosedRead(); | 264 sd->MarkClosedRead(); |
262 } else if (errno != EAGAIN) { | 265 } else if (errno != EWOULDBLOCK) { |
263 fprintf(stderr, "Error recv: %s\n", strerror(errno)); | 266 fprintf(stderr, "Error recv: %s\n", strerror(errno)); |
264 } | 267 } |
265 } | 268 } |
266 } | 269 } |
267 } | 270 } |
268 | 271 |
269 // On pipes POLLHUP is reported without POLLIN when there is no | 272 // On pipes POLLHUP is reported without POLLIN when there is no |
270 // more data to read. | 273 // more data to read. |
271 if (sd->IsPipe()) { | 274 if (sd->IsPipe()) { |
272 if (((pollfd->revents & POLLIN) == 0) && | 275 if (((pollfd->revents & POLLIN) == 0) && |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 | 342 |
340 | 343 |
341 void* EventHandlerImplementation::Poll(void* args) { | 344 void* EventHandlerImplementation::Poll(void* args) { |
342 intptr_t pollfds_size; | 345 intptr_t pollfds_size; |
343 struct pollfd* pollfds; | 346 struct pollfd* pollfds; |
344 EventHandlerImplementation* handler = | 347 EventHandlerImplementation* handler = |
345 reinterpret_cast<EventHandlerImplementation*>(args); | 348 reinterpret_cast<EventHandlerImplementation*>(args); |
346 while (1) { | 349 while (1) { |
347 pollfds = handler->GetPollFds(&pollfds_size); | 350 pollfds = handler->GetPollFds(&pollfds_size); |
348 intptr_t millis = handler->GetTimeout(); | 351 intptr_t millis = handler->GetTimeout(); |
349 intptr_t result = poll(pollfds, pollfds_size, millis); | 352 intptr_t result = TEMP_FAILURE_RETRY(poll(pollfds, pollfds_size, millis)); |
| 353 ASSERT(EAGAIN == EWOULDBLOCK); |
350 if (result == -1) { | 354 if (result == -1) { |
351 if (errno != EAGAIN && errno != EINTR) { | 355 if (errno != EWOULDBLOCK) { |
352 perror("Poll failed"); | 356 perror("Poll failed"); |
353 } | 357 } |
354 } else { | 358 } else { |
355 handler->HandleTimeout(); | 359 handler->HandleTimeout(); |
356 handler->HandleEvents(pollfds, pollfds_size, result); | 360 handler->HandleEvents(pollfds, pollfds_size, result); |
357 } | 361 } |
358 free(pollfds); | 362 free(pollfds); |
359 } | 363 } |
360 return NULL; | 364 return NULL; |
361 } | 365 } |
362 | 366 |
363 | 367 |
364 void EventHandlerImplementation::StartEventHandler() { | 368 void EventHandlerImplementation::StartEventHandler() { |
365 pthread_t handler_thread; | 369 pthread_t handler_thread; |
366 int result = pthread_create(&handler_thread, | 370 int result = pthread_create(&handler_thread, |
367 NULL, | 371 NULL, |
368 &EventHandlerImplementation::Poll, | 372 &EventHandlerImplementation::Poll, |
369 this); | 373 this); |
370 if (result != 0) { | 374 if (result != 0) { |
371 FATAL("Create start event handler thread"); | 375 FATAL("Create start event handler thread"); |
372 } | 376 } |
373 } | 377 } |
374 | 378 |
375 | 379 |
376 void EventHandlerImplementation::SendData(intptr_t id, | 380 void EventHandlerImplementation::SendData(intptr_t id, |
377 Dart_Port dart_port, | 381 Dart_Port dart_port, |
378 intptr_t data) { | 382 intptr_t data) { |
379 WakeupHandler(id, dart_port, data); | 383 WakeupHandler(id, dart_port, data); |
380 } | 384 } |
OLD | NEW |