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

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

Issue 2480793002: clang-format runtime/bin (Closed)
Patch Set: Created 4 years, 1 month 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
« no previous file with comments | « runtime/bin/eventhandler_linux.h ('k') | runtime/bin/eventhandler_macos.h » ('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) 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 #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(TARGET_OS_LINUX) 8 #if defined(TARGET_OS_LINUX)
9 9
10 #include "bin/eventhandler.h" 10 #include "bin/eventhandler.h"
11 #include "bin/eventhandler_linux.h" 11 #include "bin/eventhandler_linux.h"
12 12
13 #include <errno.h> // NOLINT 13 #include <errno.h> // NOLINT
14 #include <fcntl.h> // NOLINT 14 #include <fcntl.h> // NOLINT
15 #include <pthread.h> // NOLINT 15 #include <pthread.h> // NOLINT
16 #include <stdio.h> // NOLINT 16 #include <stdio.h> // NOLINT
17 #include <string.h> // NOLINT 17 #include <string.h> // NOLINT
18 #include <sys/epoll.h> // NOLINT 18 #include <sys/epoll.h> // NOLINT
19 #include <sys/stat.h> // NOLINT 19 #include <sys/stat.h> // NOLINT
20 #include <sys/timerfd.h> // NOLINT 20 #include <sys/timerfd.h> // NOLINT
21 #include <unistd.h> // NOLINT 21 #include <unistd.h> // NOLINT
22 22
23 #include "bin/dartutils.h" 23 #include "bin/dartutils.h"
24 #include "bin/fdutils.h" 24 #include "bin/fdutils.h"
25 #include "bin/log.h" 25 #include "bin/log.h"
26 #include "bin/lockers.h" 26 #include "bin/lockers.h"
27 #include "bin/socket.h" 27 #include "bin/socket.h"
28 #include "bin/thread.h" 28 #include "bin/thread.h"
29 #include "platform/utils.h" 29 #include "platform/utils.h"
30 30
31 namespace dart { 31 namespace dart {
32 namespace bin { 32 namespace bin {
33 33
34 intptr_t DescriptorInfo::GetPollEvents() { 34 intptr_t DescriptorInfo::GetPollEvents() {
35 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are 35 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are
36 // triggered anyway. 36 // triggered anyway.
37 intptr_t events = 0; 37 intptr_t events = 0;
38 if ((Mask() & (1 << kInEvent)) != 0) { 38 if ((Mask() & (1 << kInEvent)) != 0) {
39 events |= EPOLLIN; 39 events |= EPOLLIN;
40 } 40 }
41 if ((Mask() & (1 << kOutEvent)) != 0) { 41 if ((Mask() & (1 << kOutEvent)) != 0) {
42 events |= EPOLLOUT; 42 events |= EPOLLOUT;
43 } 43 }
44 return events; 44 return events;
45 } 45 }
46 46
47 47
48 // Unregister the file descriptor for a DescriptorInfo structure with 48 // Unregister the file descriptor for a DescriptorInfo structure with
49 // epoll. 49 // epoll.
50 static void RemoveFromEpollInstance(intptr_t epoll_fd_, 50 static void RemoveFromEpollInstance(intptr_t epoll_fd_, DescriptorInfo* di) {
51 DescriptorInfo* di) { 51 VOID_NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, di->fd(), NULL));
52 VOID_NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_,
53 EPOLL_CTL_DEL,
54 di->fd(),
55 NULL));
56 } 52 }
57 53
58 54
59 static void AddToEpollInstance(intptr_t epoll_fd_, DescriptorInfo* di) { 55 static void AddToEpollInstance(intptr_t epoll_fd_, DescriptorInfo* di) {
60 struct epoll_event event; 56 struct epoll_event event;
61 event.events = EPOLLRDHUP | di->GetPollEvents(); 57 event.events = EPOLLRDHUP | di->GetPollEvents();
62 if (!di->IsListeningSocket()) { 58 if (!di->IsListeningSocket()) {
63 event.events |= EPOLLET; 59 event.events |= EPOLLET;
64 } 60 }
65 event.data.ptr = di; 61 event.data.ptr = di;
66 int status = NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, 62 int status =
67 EPOLL_CTL_ADD, 63 NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, di->fd(), &event));
68 di->fd(),
69 &event));
70 if (status == -1) { 64 if (status == -1) {
71 // TODO(dart:io): Verify that the dart end is handling this correctly. 65 // TODO(dart:io): Verify that the dart end is handling this correctly.
72 66
73 // Epoll does not accept the file descriptor. It could be due to 67 // Epoll does not accept the file descriptor. It could be due to
74 // already closed file descriptor, or unuspported devices, such 68 // already closed file descriptor, or unuspported devices, such
75 // as /dev/null. In such case, mark the file descriptor as closed, 69 // as /dev/null. In such case, mark the file descriptor as closed,
76 // so dart will handle it accordingly. 70 // so dart will handle it accordingly.
77 di->NotifyAllDartPorts(1 << kCloseEvent); 71 di->NotifyAllDartPorts(1 << kCloseEvent);
78 } 72 }
79 } 73 }
(...skipping 15 matching lines...) Expand all
95 static const int kEpollInitialSize = 64; 89 static const int kEpollInitialSize = 64;
96 epoll_fd_ = NO_RETRY_EXPECTED(epoll_create(kEpollInitialSize)); 90 epoll_fd_ = NO_RETRY_EXPECTED(epoll_create(kEpollInitialSize));
97 if (epoll_fd_ == -1) { 91 if (epoll_fd_ == -1) {
98 FATAL1("Failed creating epoll file descriptor: %i", errno); 92 FATAL1("Failed creating epoll file descriptor: %i", errno);
99 } 93 }
100 FDUtils::SetCloseOnExec(epoll_fd_); 94 FDUtils::SetCloseOnExec(epoll_fd_);
101 // Register the interrupt_fd with the epoll instance. 95 // Register the interrupt_fd with the epoll instance.
102 struct epoll_event event; 96 struct epoll_event event;
103 event.events = EPOLLIN; 97 event.events = EPOLLIN;
104 event.data.ptr = NULL; 98 event.data.ptr = NULL;
105 int status = NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, 99 int status = NO_RETRY_EXPECTED(
106 EPOLL_CTL_ADD, 100 epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupt_fds_[0], &event));
107 interrupt_fds_[0],
108 &event));
109 if (status == -1) { 101 if (status == -1) {
110 FATAL("Failed adding interrupt fd to epoll instance"); 102 FATAL("Failed adding interrupt fd to epoll instance");
111 } 103 }
112 timer_fd_ = NO_RETRY_EXPECTED(timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC)); 104 timer_fd_ = NO_RETRY_EXPECTED(timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC));
113 if (timer_fd_ == -1) { 105 if (timer_fd_ == -1) {
114 FATAL1("Failed creating timerfd file descriptor: %i", errno); 106 FATAL1("Failed creating timerfd file descriptor: %i", errno);
115 } 107 }
116 // Register the timer_fd_ with the epoll instance. 108 // Register the timer_fd_ with the epoll instance.
117 event.events = EPOLLIN; 109 event.events = EPOLLIN;
118 event.data.fd = timer_fd_; 110 event.data.fd = timer_fd_;
119 status = NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, 111 status =
120 EPOLL_CTL_ADD, 112 NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &event));
121 timer_fd_,
122 &event));
123 if (status == -1) { 113 if (status == -1) {
124 FATAL2( 114 FATAL2("Failed adding timerfd fd(%i) to epoll instance: %i", timer_fd_,
125 "Failed adding timerfd fd(%i) to epoll instance: %i", timer_fd_, errno); 115 errno);
126 } 116 }
127 } 117 }
128 118
129 119
130 static void DeleteDescriptorInfo(void* info) { 120 static void DeleteDescriptorInfo(void* info) {
131 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info); 121 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info);
132 di->Close(); 122 di->Close();
133 delete di; 123 delete di;
134 } 124 }
135 125
136 126
137 EventHandlerImplementation::~EventHandlerImplementation() { 127 EventHandlerImplementation::~EventHandlerImplementation() {
138 socket_map_.Clear(DeleteDescriptorInfo); 128 socket_map_.Clear(DeleteDescriptorInfo);
139 VOID_TEMP_FAILURE_RETRY(close(epoll_fd_)); 129 VOID_TEMP_FAILURE_RETRY(close(epoll_fd_));
140 VOID_TEMP_FAILURE_RETRY(close(timer_fd_)); 130 VOID_TEMP_FAILURE_RETRY(close(timer_fd_));
141 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); 131 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0]));
142 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); 132 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1]));
143 } 133 }
144 134
145 135
146 void EventHandlerImplementation::UpdateEpollInstance(intptr_t old_mask, 136 void EventHandlerImplementation::UpdateEpollInstance(intptr_t old_mask,
147 DescriptorInfo *di) { 137 DescriptorInfo* di) {
148 intptr_t new_mask = di->Mask(); 138 intptr_t new_mask = di->Mask();
149 if ((old_mask != 0) && (new_mask == 0)) { 139 if ((old_mask != 0) && (new_mask == 0)) {
150 RemoveFromEpollInstance(epoll_fd_, di); 140 RemoveFromEpollInstance(epoll_fd_, di);
151 } else if ((old_mask == 0) && (new_mask != 0)) { 141 } else if ((old_mask == 0) && (new_mask != 0)) {
152 AddToEpollInstance(epoll_fd_, di); 142 AddToEpollInstance(epoll_fd_, di);
153 } else if ((old_mask != 0) && (new_mask != 0) && (old_mask != new_mask)) { 143 } else if ((old_mask != 0) && (new_mask != 0) && (old_mask != new_mask)) {
154 ASSERT(!di->IsListeningSocket()); 144 ASSERT(!di->IsListeningSocket());
155 RemoveFromEpollInstance(epoll_fd_, di); 145 RemoveFromEpollInstance(epoll_fd_, di);
156 AddToEpollInstance(epoll_fd_, di); 146 AddToEpollInstance(epoll_fd_, di);
157 } 147 }
158 } 148 }
159 149
160 150
161 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( 151 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo(
162 intptr_t fd, bool is_listening) { 152 intptr_t fd,
153 bool is_listening) {
163 ASSERT(fd >= 0); 154 ASSERT(fd >= 0);
164 HashMap::Entry* entry = socket_map_.Lookup( 155 HashMap::Entry* entry = socket_map_.Lookup(GetHashmapKeyFromFd(fd),
165 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true); 156 GetHashmapHashFromFd(fd), true);
166 ASSERT(entry != NULL); 157 ASSERT(entry != NULL);
167 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(entry->value); 158 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(entry->value);
168 if (di == NULL) { 159 if (di == NULL) {
169 // If there is no data in the hash map for this file descriptor a 160 // If there is no data in the hash map for this file descriptor a
170 // new DescriptorInfo for the file descriptor is inserted. 161 // new DescriptorInfo for the file descriptor is inserted.
171 if (is_listening) { 162 if (is_listening) {
172 di = new DescriptorInfoMultiple(fd); 163 di = new DescriptorInfoMultiple(fd);
173 } else { 164 } else {
174 di = new DescriptorInfoSingle(fd); 165 di = new DescriptorInfoSingle(fd);
175 } 166 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 it.it_value.tv_sec = millis / 1000; 208 it.it_value.tv_sec = millis / 1000;
218 it.it_value.tv_nsec = (millis % 1000) * 1000000; 209 it.it_value.tv_nsec = (millis % 1000) * 1000000;
219 } 210 }
220 VOID_NO_RETRY_EXPECTED( 211 VOID_NO_RETRY_EXPECTED(
221 timerfd_settime(timer_fd_, TFD_TIMER_ABSTIME, &it, NULL)); 212 timerfd_settime(timer_fd_, TFD_TIMER_ABSTIME, &it, NULL));
222 } else if (msg[i].id == kShutdownId) { 213 } else if (msg[i].id == kShutdownId) {
223 shutdown_ = true; 214 shutdown_ = true;
224 } else { 215 } else {
225 ASSERT((msg[i].data & COMMAND_MASK) != 0); 216 ASSERT((msg[i].data & COMMAND_MASK) != 0);
226 217
227 DescriptorInfo* di = GetDescriptorInfo( 218 DescriptorInfo* di =
228 msg[i].id, IS_LISTENING_SOCKET(msg[i].data)); 219 GetDescriptorInfo(msg[i].id, IS_LISTENING_SOCKET(msg[i].data));
229 if (IS_COMMAND(msg[i].data, kShutdownReadCommand)) { 220 if (IS_COMMAND(msg[i].data, kShutdownReadCommand)) {
230 ASSERT(!di->IsListeningSocket()); 221 ASSERT(!di->IsListeningSocket());
231 // Close the socket for reading. 222 // Close the socket for reading.
232 VOID_NO_RETRY_EXPECTED(shutdown(di->fd(), SHUT_RD)); 223 VOID_NO_RETRY_EXPECTED(shutdown(di->fd(), SHUT_RD));
233 } else if (IS_COMMAND(msg[i].data, kShutdownWriteCommand)) { 224 } else if (IS_COMMAND(msg[i].data, kShutdownWriteCommand)) {
234 ASSERT(!di->IsListeningSocket()); 225 ASSERT(!di->IsListeningSocket());
235 // Close the socket for writing. 226 // Close the socket for writing.
236 VOID_NO_RETRY_EXPECTED(shutdown(di->fd(), SHUT_WR)); 227 VOID_NO_RETRY_EXPECTED(shutdown(di->fd(), SHUT_WR));
237 } else if (IS_COMMAND(msg[i].data, kCloseCommand)) { 228 } else if (IS_COMMAND(msg[i].data, kCloseCommand)) {
238 // Close the socket and free system resources and move on to next 229 // Close the socket and free system resources and move on to next
239 // message. 230 // message.
240 intptr_t old_mask = di->Mask(); 231 intptr_t old_mask = di->Mask();
241 Dart_Port port = msg[i].dart_port; 232 Dart_Port port = msg[i].dart_port;
242 di->RemovePort(port); 233 di->RemovePort(port);
243 intptr_t new_mask = di->Mask(); 234 intptr_t new_mask = di->Mask();
244 UpdateEpollInstance(old_mask, di); 235 UpdateEpollInstance(old_mask, di);
245 236
246 intptr_t fd = di->fd(); 237 intptr_t fd = di->fd();
247 if (di->IsListeningSocket()) { 238 if (di->IsListeningSocket()) {
248 // We only close the socket file descriptor from the operating 239 // We only close the socket file descriptor from the operating
249 // system if there are no other dart socket objects which 240 // system if there are no other dart socket objects which
250 // are listening on the same (address, port) combination. 241 // are listening on the same (address, port) combination.
251 ListeningSocketRegistry *registry = 242 ListeningSocketRegistry* registry =
252 ListeningSocketRegistry::Instance(); 243 ListeningSocketRegistry::Instance();
253 244
254 MutexLocker locker(registry->mutex()); 245 MutexLocker locker(registry->mutex());
255 246
256 if (registry->CloseSafe(fd)) { 247 if (registry->CloseSafe(fd)) {
257 ASSERT(new_mask == 0); 248 ASSERT(new_mask == 0);
258 socket_map_.Remove(GetHashmapKeyFromFd(fd), 249 socket_map_.Remove(GetHashmapKeyFromFd(fd),
259 GetHashmapHashFromFd(fd)); 250 GetHashmapHashFromFd(fd));
260 di->Close(); 251 di->Close();
261 delete di; 252 delete di;
262 } 253 }
263 } else { 254 } else {
264 ASSERT(new_mask == 0); 255 ASSERT(new_mask == 0);
265 socket_map_.Remove( 256 socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd));
266 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd));
267 di->Close(); 257 di->Close();
268 delete di; 258 delete di;
269 } 259 }
270 260
271 DartUtils::PostInt32(port, 1 << kDestroyedEvent); 261 DartUtils::PostInt32(port, 1 << kDestroyedEvent);
272 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) { 262 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) {
273 int count = TOKEN_COUNT(msg[i].data); 263 int count = TOKEN_COUNT(msg[i].data);
274 intptr_t old_mask = di->Mask(); 264 intptr_t old_mask = di->Mask();
275 di->ReturnTokens(msg[i].dart_port, count); 265 di->ReturnTokens(msg[i].dart_port, count);
276 UpdateEpollInstance(old_mask, di); 266 UpdateEpollInstance(old_mask, di);
(...skipping 27 matching lines...) Expand all
304 } 294 }
305 if ((events & EPOLLERR) != 0) { 295 if ((events & EPOLLERR) != 0) {
306 Log::Print("EPOLLERR "); 296 Log::Print("EPOLLERR ");
307 } 297 }
308 if ((events & EPOLLHUP) != 0) { 298 if ((events & EPOLLHUP) != 0) {
309 Log::Print("EPOLLHUP "); 299 Log::Print("EPOLLHUP ");
310 } 300 }
311 if ((events & EPOLLRDHUP) != 0) { 301 if ((events & EPOLLRDHUP) != 0) {
312 Log::Print("EPOLLRDHUP "); 302 Log::Print("EPOLLRDHUP ");
313 } 303 }
314 int all_events = EPOLLIN | EPOLLPRI | EPOLLOUT | 304 int all_events =
315 EPOLLERR | EPOLLHUP | EPOLLRDHUP; 305 EPOLLIN | EPOLLPRI | EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLRDHUP;
316 if ((events & ~all_events) != 0) { 306 if ((events & ~all_events) != 0) {
317 Log::Print("(and %08x) ", events & ~all_events); 307 Log::Print("(and %08x) ", events & ~all_events);
318 } 308 }
319 Log::Print("(available %d) ", FDUtils::AvailableBytes(fd)); 309 Log::Print("(available %d) ", FDUtils::AvailableBytes(fd));
320 310
321 Log::Print("\n"); 311 Log::Print("\n");
322 } 312 }
323 #endif 313 #endif
324 314
325 315
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 // The hashmap does not support keys with value 0. 432 // The hashmap does not support keys with value 0.
443 return dart::Utils::WordHash(fd + 1); 433 return dart::Utils::WordHash(fd + 1);
444 } 434 }
445 435
446 } // namespace bin 436 } // namespace bin
447 } // namespace dart 437 } // namespace dart
448 438
449 #endif // defined(TARGET_OS_LINUX) 439 #endif // defined(TARGET_OS_LINUX)
450 440
451 #endif // !defined(DART_IO_DISABLED) 441 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/eventhandler_linux.h ('k') | runtime/bin/eventhandler_macos.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698