Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(340)

Side by Side Diff: runtime/bin/eventhandler_macos.cc

Issue 9139011: Handle EINTR on all IO operations (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixed building on Mac OS Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/eventhandler_linux.cc ('k') | runtime/bin/fdutils_linux.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « runtime/bin/eventhandler_linux.cc ('k') | runtime/bin/fdutils_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698