| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 #if !defined(DART_IO_DISABLED) | 5 #if !defined(DART_IO_DISABLED) |
| 6 | 6 |
| 7 #include "platform/globals.h" | 7 #include "platform/globals.h" |
| 8 #if defined(HOST_OS_FUCHSIA) | 8 #if defined(HOST_OS_FUCHSIA) |
| 9 | 9 |
| 10 #include "bin/eventhandler.h" | 10 #include "bin/eventhandler.h" |
| 11 #include "bin/eventhandler_fuchsia.h" | 11 #include "bin/eventhandler_fuchsia.h" |
| 12 | 12 |
| 13 #include <errno.h> | 13 #include <errno.h> |
| 14 #include <fcntl.h> | 14 #include <fcntl.h> |
| 15 #include <magenta/status.h> | 15 #include <magenta/status.h> |
| 16 #include <magenta/syscalls.h> | 16 #include <magenta/syscalls.h> |
| 17 #include <magenta/syscalls/object.h> | 17 #include <magenta/syscalls/object.h> |
| 18 #include <magenta/syscalls/port.h> | 18 #include <magenta/syscalls/port.h> |
| 19 #include <mxio/private.h> | 19 #include <mxio/private.h> |
| 20 #include <poll.h> |
| 20 #include <pthread.h> | 21 #include <pthread.h> |
| 21 #include <stdio.h> | 22 #include <stdio.h> |
| 22 #include <string.h> | 23 #include <string.h> |
| 23 #include <sys/epoll.h> | |
| 24 #include <sys/socket.h> | 24 #include <sys/socket.h> |
| 25 #include <sys/stat.h> | 25 #include <sys/stat.h> |
| 26 #include <unistd.h> | 26 #include <unistd.h> |
| 27 | 27 |
| 28 #include "bin/fdutils.h" | 28 #include "bin/fdutils.h" |
| 29 #include "bin/lockers.h" | 29 #include "bin/lockers.h" |
| 30 #include "bin/log.h" | 30 #include "bin/log.h" |
| 31 #include "bin/socket.h" | 31 #include "bin/socket.h" |
| 32 #include "bin/thread.h" | 32 #include "bin/thread.h" |
| 33 #include "bin/utils.h" | 33 #include "bin/utils.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 MutexLocker ml(mutex_); | 82 MutexLocker ml(mutex_); |
| 83 const ssize_t read_bytes = NO_RETRY_EXPECTED(read(fd_, buffer, num_bytes)); | 83 const ssize_t read_bytes = NO_RETRY_EXPECTED(read(fd_, buffer, num_bytes)); |
| 84 const int err = errno; | 84 const int err = errno; |
| 85 LOG_INFO("IOHandle::Read: fd = %ld. read %ld bytes\n", fd_, read_bytes); | 85 LOG_INFO("IOHandle::Read: fd = %ld. read %ld bytes\n", fd_, read_bytes); |
| 86 | 86 |
| 87 // Resubscribe to read events. We resubscribe to events even if read() returns | 87 // Resubscribe to read events. We resubscribe to events even if read() returns |
| 88 // an error. The error might be, e.g. EWOULDBLOCK, in which case | 88 // an error. The error might be, e.g. EWOULDBLOCK, in which case |
| 89 // re-subscription is necessary. Logic in the caller decides which errors are | 89 // re-subscription is necessary. Logic in the caller decides which errors are |
| 90 // real, and which are ignore-and-continue. | 90 // real, and which are ignore-and-continue. |
| 91 read_events_enabled_ = true; | 91 read_events_enabled_ = true; |
| 92 if (!AsyncWaitLocked(MX_HANDLE_INVALID, EPOLLIN, wait_key_)) { | 92 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLIN, wait_key_)) { |
| 93 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); | 93 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); |
| 94 } | 94 } |
| 95 | 95 |
| 96 errno = err; | 96 errno = err; |
| 97 return read_bytes; | 97 return read_bytes; |
| 98 } | 98 } |
| 99 | 99 |
| 100 | 100 |
| 101 intptr_t IOHandle::Write(const void* buffer, intptr_t num_bytes) { | 101 intptr_t IOHandle::Write(const void* buffer, intptr_t num_bytes) { |
| 102 MutexLocker ml(mutex_); | 102 MutexLocker ml(mutex_); |
| 103 const ssize_t written_bytes = | 103 const ssize_t written_bytes = |
| 104 NO_RETRY_EXPECTED(write(fd_, buffer, num_bytes)); | 104 NO_RETRY_EXPECTED(write(fd_, buffer, num_bytes)); |
| 105 const int err = errno; | 105 const int err = errno; |
| 106 LOG_INFO("IOHandle::Write: fd = %ld. wrote %ld bytes\n", fd_, written_bytes); | 106 LOG_INFO("IOHandle::Write: fd = %ld. wrote %ld bytes\n", fd_, written_bytes); |
| 107 | 107 |
| 108 // Resubscribe to write events. | 108 // Resubscribe to write events. |
| 109 write_events_enabled_ = true; | 109 write_events_enabled_ = true; |
| 110 if (!AsyncWaitLocked(MX_HANDLE_INVALID, EPOLLOUT, wait_key_)) { | 110 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLOUT, wait_key_)) { |
| 111 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); | 111 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); |
| 112 } | 112 } |
| 113 | 113 |
| 114 errno = err; | 114 errno = err; |
| 115 return written_bytes; | 115 return written_bytes; |
| 116 } | 116 } |
| 117 | 117 |
| 118 | 118 |
| 119 intptr_t IOHandle::Accept(struct sockaddr* addr, socklen_t* addrlen) { | 119 intptr_t IOHandle::Accept(struct sockaddr* addr, socklen_t* addrlen) { |
| 120 MutexLocker ml(mutex_); | 120 MutexLocker ml(mutex_); |
| 121 const intptr_t socket = NO_RETRY_EXPECTED(accept(fd_, addr, addrlen)); | 121 const intptr_t socket = NO_RETRY_EXPECTED(accept(fd_, addr, addrlen)); |
| 122 const int err = errno; | 122 const int err = errno; |
| 123 LOG_INFO("IOHandle::Accept: fd = %ld. socket = %ld\n", fd_, socket); | 123 LOG_INFO("IOHandle::Accept: fd = %ld. socket = %ld\n", fd_, socket); |
| 124 | 124 |
| 125 // Re-subscribe to read events. | 125 // Re-subscribe to read events. |
| 126 read_events_enabled_ = true; | 126 read_events_enabled_ = true; |
| 127 if (!AsyncWaitLocked(MX_HANDLE_INVALID, EPOLLIN, wait_key_)) { | 127 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLIN, wait_key_)) { |
| 128 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); | 128 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); |
| 129 } | 129 } |
| 130 | 130 |
| 131 errno = err; | 131 errno = err; |
| 132 return socket; | 132 return socket; |
| 133 } | 133 } |
| 134 | 134 |
| 135 | 135 |
| 136 void IOHandle::Close() { | 136 void IOHandle::Close() { |
| 137 MutexLocker ml(mutex_); | 137 MutexLocker ml(mutex_); |
| 138 VOID_NO_RETRY_EXPECTED(close(fd_)); | 138 VOID_NO_RETRY_EXPECTED(close(fd_)); |
| 139 } | 139 } |
| 140 | 140 |
| 141 | 141 |
| 142 uint32_t IOHandle::MaskToEpollEvents(intptr_t mask) { | 142 uint32_t IOHandle::MaskToEpollEvents(intptr_t mask) { |
| 143 MutexLocker ml(mutex_); | 143 MutexLocker ml(mutex_); |
| 144 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are | 144 // Do not ask for POLLERR and POLLHUP explicitly as they are |
| 145 // triggered anyway. | 145 // triggered anyway. |
| 146 uint32_t events = EPOLLRDHUP; | 146 uint32_t events = POLLRDHUP; |
| 147 if (read_events_enabled_ && ((mask & (1 << kInEvent)) != 0)) { | 147 if (read_events_enabled_ && ((mask & (1 << kInEvent)) != 0)) { |
| 148 events |= EPOLLIN; | 148 events |= POLLIN; |
| 149 } | 149 } |
| 150 if (write_events_enabled_ && ((mask & (1 << kOutEvent)) != 0)) { | 150 if (write_events_enabled_ && ((mask & (1 << kOutEvent)) != 0)) { |
| 151 events |= EPOLLOUT; | 151 events |= POLLOUT; |
| 152 } | 152 } |
| 153 return events; | 153 return events; |
| 154 } | 154 } |
| 155 | 155 |
| 156 | 156 |
| 157 intptr_t IOHandle::EpollEventsToMask(intptr_t events) { | 157 intptr_t IOHandle::EpollEventsToMask(intptr_t events) { |
| 158 if ((events & EPOLLERR) != 0) { | 158 if ((events & POLLERR) != 0) { |
| 159 // Return error only if EPOLLIN is present. | 159 // Return error only if POLLIN is present. |
| 160 return ((events & EPOLLIN) != 0) ? (1 << kErrorEvent) : 0; | 160 return ((events & POLLIN) != 0) ? (1 << kErrorEvent) : 0; |
| 161 } | 161 } |
| 162 intptr_t event_mask = 0; | 162 intptr_t event_mask = 0; |
| 163 if ((events & EPOLLIN) != 0) { | 163 if ((events & POLLIN) != 0) { |
| 164 event_mask |= (1 << kInEvent); | 164 event_mask |= (1 << kInEvent); |
| 165 } | 165 } |
| 166 if ((events & EPOLLOUT) != 0) { | 166 if ((events & POLLOUT) != 0) { |
| 167 event_mask |= (1 << kOutEvent); | 167 event_mask |= (1 << kOutEvent); |
| 168 } | 168 } |
| 169 if ((events & (EPOLLHUP | EPOLLRDHUP)) != 0) { | 169 if ((events & (POLLHUP | POLLRDHUP)) != 0) { |
| 170 event_mask |= (1 << kCloseEvent); | 170 event_mask |= (1 << kCloseEvent); |
| 171 } | 171 } |
| 172 return event_mask; | 172 return event_mask; |
| 173 } | 173 } |
| 174 | 174 |
| 175 | 175 |
| 176 bool IOHandle::AsyncWaitLocked(mx_handle_t port, | 176 bool IOHandle::AsyncWaitLocked(mx_handle_t port, |
| 177 uint32_t events, | 177 uint32_t events, |
| 178 uint64_t key) { | 178 uint64_t key) { |
| 179 LOG_INFO("IOHandle::AsyncWait: fd = %ld\n", fd_); | 179 LOG_INFO("IOHandle::AsyncWait: fd = %ld\n", fd_); |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 // The hashmap does not support keys with value 0. | 582 // The hashmap does not support keys with value 0. |
| 583 return dart::Utils::WordHash(fd + 1); | 583 return dart::Utils::WordHash(fd + 1); |
| 584 } | 584 } |
| 585 | 585 |
| 586 } // namespace bin | 586 } // namespace bin |
| 587 } // namespace dart | 587 } // namespace dart |
| 588 | 588 |
| 589 #endif // defined(HOST_OS_FUCHSIA) | 589 #endif // defined(HOST_OS_FUCHSIA) |
| 590 | 590 |
| 591 #endif // !defined(DART_IO_DISABLED) | 591 #endif // !defined(DART_IO_DISABLED) |
| OLD | NEW |