| 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 |