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