OLD | NEW |
1 // Copyright (c) 2011, 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> |
11 #include <unistd.h> | 11 #include <unistd.h> |
(...skipping 36 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 // end-of-file. | 247 // end-of-file. |
247 if (sd->fd() == STDIN_FILENO) { | 248 if (sd->fd() == STDIN_FILENO) { |
248 event_mask = (1 << kCloseEvent); | 249 event_mask = (1 << kCloseEvent); |
249 sd->MarkClosedRead(); | 250 sd->MarkClosedRead(); |
250 } | 251 } |
251 } else { | 252 } else { |
252 // If POLLIN is set with no available data and no POLLHUP use | 253 // If POLLIN is set with no available data and no POLLHUP use |
253 // recv to peek for whether the other end of the socket | 254 // recv to peek for whether the other end of the socket |
254 // actually closed. | 255 // actually closed. |
255 char buffer; | 256 char buffer; |
256 ssize_t bytesPeeked = recv(sd->fd(), &buffer, 1, MSG_PEEK); | 257 ssize_t bytesPeeked = |
| 258 TEMP_FAILURE_RETRY(recv(sd->fd(), &buffer, 1, MSG_PEEK)); |
| 259 ASSERT(EAGAIN == EWOULDBLOCK); |
257 if (bytesPeeked == 0) { | 260 if (bytesPeeked == 0) { |
258 event_mask = (1 << kCloseEvent); | 261 event_mask = (1 << kCloseEvent); |
259 sd->MarkClosedRead(); | 262 sd->MarkClosedRead(); |
260 } else if (errno != EAGAIN) { | 263 } else if (errno != EWOULDBLOCK) { |
261 fprintf(stderr, "Error recv: %s\n", strerror(errno)); | 264 fprintf(stderr, "Error recv: %s\n", strerror(errno)); |
262 } | 265 } |
263 } | 266 } |
264 } | 267 } |
265 } | 268 } |
266 | 269 |
267 // On pipes POLLHUP is reported without POLLIN when there is no | 270 // On pipes POLLHUP is reported without POLLIN when there is no |
268 // more data to read. | 271 // more data to read. |
269 if (sd->IsPipe()) { | 272 if (sd->IsPipe()) { |
270 if (((pollfd->revents & POLLIN) == 0) && | 273 if (((pollfd->revents & POLLIN) == 0) && |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 | 340 |
338 | 341 |
339 void* EventHandlerImplementation::Poll(void* args) { | 342 void* EventHandlerImplementation::Poll(void* args) { |
340 intptr_t pollfds_size; | 343 intptr_t pollfds_size; |
341 struct pollfd* pollfds; | 344 struct pollfd* pollfds; |
342 EventHandlerImplementation* handler = | 345 EventHandlerImplementation* handler = |
343 reinterpret_cast<EventHandlerImplementation*>(args); | 346 reinterpret_cast<EventHandlerImplementation*>(args); |
344 while (1) { | 347 while (1) { |
345 pollfds = handler->GetPollFds(&pollfds_size); | 348 pollfds = handler->GetPollFds(&pollfds_size); |
346 intptr_t millis = handler->GetTimeout(); | 349 intptr_t millis = handler->GetTimeout(); |
347 intptr_t result = poll(pollfds, pollfds_size, millis); | 350 intptr_t result = TEMP_FAILURE_RETRY(poll(pollfds, pollfds_size, millis)); |
| 351 ASSERT(EAGAIN == EWOULDBLOCK); |
348 if (result == -1) { | 352 if (result == -1) { |
349 if (errno != EAGAIN && errno != EINTR) { | 353 if (errno != EWOULDBLOCK) { |
350 perror("Poll failed"); | 354 perror("Poll failed"); |
351 } | 355 } |
352 } else { | 356 } else { |
353 handler->HandleTimeout(); | 357 handler->HandleTimeout(); |
354 handler->HandleEvents(pollfds, pollfds_size, result); | 358 handler->HandleEvents(pollfds, pollfds_size, result); |
355 } | 359 } |
356 free(pollfds); | 360 free(pollfds); |
357 } | 361 } |
358 return NULL; | 362 return NULL; |
359 } | 363 } |
360 | 364 |
361 | 365 |
362 void EventHandlerImplementation::StartEventHandler() { | 366 void EventHandlerImplementation::StartEventHandler() { |
363 pthread_t handler_thread; | 367 pthread_t handler_thread; |
364 int result = pthread_create(&handler_thread, | 368 int result = pthread_create(&handler_thread, |
365 NULL, | 369 NULL, |
366 &EventHandlerImplementation::Poll, | 370 &EventHandlerImplementation::Poll, |
367 this); | 371 this); |
368 if (result != 0) { | 372 if (result != 0) { |
369 FATAL("Create start event handler thread"); | 373 FATAL("Create start event handler thread"); |
370 } | 374 } |
371 } | 375 } |
372 | 376 |
373 | 377 |
374 void EventHandlerImplementation::SendData(intptr_t id, | 378 void EventHandlerImplementation::SendData(intptr_t id, |
375 Dart_Port dart_port, | 379 Dart_Port dart_port, |
376 intptr_t data) { | 380 intptr_t data) { |
377 WakeupHandler(id, dart_port, data); | 381 WakeupHandler(id, dart_port, data); |
378 } | 382 } |
OLD | NEW |