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

Side by Side Diff: net/tools/epoll_server/epoll_server.cc

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/tools/epoll_server/epoll_server.h" 5 #include "net/tools/epoll_server/epoll_server.h"
6 6
7 #include <unistd.h> // For read, pipe, close and write. 7 #include <unistd.h> // For read, pipe, close and write.
8 #include <stdlib.h> // for abort 8 #include <stdlib.h> // for abort
9 #include <errno.h> // for errno and strerror_r 9 #include <errno.h> // for errno and strerror_r
10 #include <algorithm> 10 #include <algorithm>
11 #include <utility> 11 #include <utility>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/timer/timer.h" 15 #include "base/timer/timer.h"
16 16
17 // Design notes: An efficient implementation of ready list has the following 17 // Design notes: An efficient implementation of ready list has the following
18 // desirable properties: 18 // desirable properties:
19 // 19 //
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 public: 62 public:
63 virtual void OnEvent(int fd, EpollEvent* event) OVERRIDE { 63 virtual void OnEvent(int fd, EpollEvent* event) OVERRIDE {
64 DCHECK(event->in_events == EPOLLIN); 64 DCHECK(event->in_events == EPOLLIN);
65 int data; 65 int data;
66 int data_read = 1; 66 int data_read = 1;
67 // Read until the pipe is empty. 67 // Read until the pipe is empty.
68 while (data_read > 0) { 68 while (data_read > 0) {
69 data_read = read(fd, &data, sizeof(data)); 69 data_read = read(fd, &data, sizeof(data));
70 } 70 }
71 } 71 }
72 virtual void OnShutdown(EpollServer *eps, int fd) OVERRIDE {} 72 virtual void OnShutdown(EpollServer* eps, int fd) OVERRIDE {}
73 virtual void OnRegistration(EpollServer*, int, int) OVERRIDE {} 73 virtual void OnRegistration(EpollServer*, int, int) OVERRIDE {}
74 virtual void OnModification(int, int) OVERRIDE {} // COV_NF_LINE 74 virtual void OnModification(int, int) OVERRIDE {} // COV_NF_LINE
75 virtual void OnUnregistration(int, bool) OVERRIDE {} // COV_NF_LINE 75 virtual void OnUnregistration(int, bool) OVERRIDE {} // COV_NF_LINE
76 }; 76 };
77 77
78 //////////////////////////////////////////////////////////////////////////////// 78 ////////////////////////////////////////////////////////////////////////////////
79 //////////////////////////////////////////////////////////////////////////////// 79 ////////////////////////////////////////////////////////////////////////////////
80 80
81 EpollServer::EpollServer() 81 EpollServer::EpollServer()
82 : epoll_fd_(epoll_create(1024)), 82 : epoll_fd_(epoll_create(1024)),
83 timeout_in_us_(0), 83 timeout_in_us_(0),
84 recorded_now_in_us_(0), 84 recorded_now_in_us_(0),
85 ready_list_size_(0), 85 ready_list_size_(0),
86 wake_cb_(new ReadPipeCallback), 86 wake_cb_(new ReadPipeCallback),
87 read_fd_(-1), 87 read_fd_(-1),
88 write_fd_(-1), 88 write_fd_(-1),
89 in_wait_for_events_and_execute_callbacks_(false), 89 in_wait_for_events_and_execute_callbacks_(false),
90 in_shutdown_(false) { 90 in_shutdown_(false) {
91 // ensure that the epoll_fd_ is valid. 91 // ensure that the epoll_fd_ is valid.
92 CHECK_NE(epoll_fd_, -1); 92 CHECK_NE(epoll_fd_, -1);
93 LIST_INIT(&ready_list_); 93 LIST_INIT(&ready_list_);
94 LIST_INIT(&tmp_list_); 94 LIST_INIT(&tmp_list_);
95 95
96 int pipe_fds[2]; 96 int pipe_fds[2];
97 if (pipe(pipe_fds) < 0) { 97 if (pipe(pipe_fds) < 0) {
98 // Unfortunately, it is impossible to test any such initialization in 98 // Unfortunately, it is impossible to test any such initialization in
99 // a constructor (as virtual methods do not yet work). 99 // a constructor (as virtual methods do not yet work).
100 // This -could- be solved by moving initialization to an outside 100 // This -could- be solved by moving initialization to an outside
(...skipping 23 matching lines...) Expand all
124 cb_iter = cb_map_.begin(); 124 cb_iter = cb_map_.begin();
125 } 125 }
126 } 126 }
127 127
128 void EpollServer::CleanupTimeToAlarmCBMap() { 128 void EpollServer::CleanupTimeToAlarmCBMap() {
129 TimeToAlarmCBMap::iterator erase_it; 129 TimeToAlarmCBMap::iterator erase_it;
130 130
131 // Call OnShutdown() on alarms. Note that the structure of the loop 131 // Call OnShutdown() on alarms. Note that the structure of the loop
132 // is similar to the structure of loop in the function HandleAlarms() 132 // is similar to the structure of loop in the function HandleAlarms()
133 for (TimeToAlarmCBMap::iterator i = alarm_map_.begin(); 133 for (TimeToAlarmCBMap::iterator i = alarm_map_.begin();
134 i != alarm_map_.end(); 134 i != alarm_map_.end();) {
135 ) {
136 // Note that OnShutdown() can call UnregisterAlarm() on 135 // Note that OnShutdown() can call UnregisterAlarm() on
137 // other iterators. OnShutdown() should not call UnregisterAlarm() 136 // other iterators. OnShutdown() should not call UnregisterAlarm()
138 // on self because by definition the iterator is not valid any more. 137 // on self because by definition the iterator is not valid any more.
139 i->second->OnShutdown(this); 138 i->second->OnShutdown(this);
140 erase_it = i; 139 erase_it = i;
141 ++i; 140 ++i;
142 alarm_map_.erase(erase_it); 141 alarm_map_.erase(erase_it);
143 } 142 }
144 } 143 }
145 144
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 AddFD(fd, event_mask); 206 AddFD(fd, event_mask);
208 } 207 }
209 fd_i->cb = cb; 208 fd_i->cb = cb;
210 fd_i->event_mask = event_mask; 209 fd_i->event_mask = event_mask;
211 fd_i->events_to_fake = 0; 210 fd_i->events_to_fake = 0;
212 } else { 211 } else {
213 AddFD(fd, event_mask); 212 AddFD(fd, event_mask);
214 cb_map_.insert(CBAndEventMask(cb, event_mask, fd)); 213 cb_map_.insert(CBAndEventMask(cb, event_mask, fd));
215 } 214 }
216 215
217
218 // set the FD to be non-blocking. 216 // set the FD to be non-blocking.
219 SetNonblocking(fd); 217 SetNonblocking(fd);
220 218
221 cb->OnRegistration(this, fd, event_mask); 219 cb->OnRegistration(this, fd, event_mask);
222 } 220 }
223 221
224 int EpollServer::GetFlags(int fd) { 222 int EpollServer::GetFlags(int fd) {
225 return fcntl(fd, F_GETFL, 0); 223 return fcntl(fd, F_GETFL, 0);
226 } 224 }
227 225
228 void EpollServer::SetNonblocking(int fd) { 226 void EpollServer::SetNonblocking(int fd) {
229 int flags = GetFlags(fd); 227 int flags = GetFlags(fd);
230 if (flags == -1) { 228 if (flags == -1) {
231 int saved_errno = errno; 229 int saved_errno = errno;
232 char buf[kErrorBufferSize]; 230 char buf[kErrorBufferSize];
233 LOG(FATAL) << "Error " << saved_errno 231 LOG(FATAL) << "Error " << saved_errno << " doing fcntl(" << fd
234 << " doing fcntl(" << fd << ", F_GETFL, 0): " 232 << ", F_GETFL, 0): "
235 << strerror_r(saved_errno, buf, sizeof(buf)); 233 << strerror_r(saved_errno, buf, sizeof(buf));
236 } 234 }
237 if (!(flags & O_NONBLOCK)) { 235 if (!(flags & O_NONBLOCK)) {
238 int saved_flags = flags; 236 int saved_flags = flags;
239 flags = SetFlags(fd, flags | O_NONBLOCK); 237 flags = SetFlags(fd, flags | O_NONBLOCK);
240 if (flags == -1) { 238 if (flags == -1) {
241 // bad. 239 // bad.
242 int saved_errno = errno; 240 int saved_errno = errno;
243 char buf[kErrorBufferSize]; 241 char buf[kErrorBufferSize];
244 LOG(FATAL) << "Error " << saved_errno 242 LOG(FATAL) << "Error " << saved_errno << " doing fcntl(" << fd
245 << " doing fcntl(" << fd << ", F_SETFL, " << saved_flags << "): " 243 << ", F_SETFL, " << saved_flags
246 << strerror_r(saved_errno, buf, sizeof(buf)); 244 << "): " << strerror_r(saved_errno, buf, sizeof(buf));
247 } 245 }
248 } 246 }
249 } 247 }
250 248
251 int EpollServer::epoll_wait_impl(int epfd, 249 int EpollServer::epoll_wait_impl(int epfd,
252 struct epoll_event* events, 250 struct epoll_event* events,
253 int max_events, 251 int max_events,
254 int timeout_in_ms) { 252 int timeout_in_ms) {
255 return epoll_wait(epfd, events, max_events, timeout_in_ms); 253 return epoll_wait(epfd, events, max_events, timeout_in_ms);
256 } 254 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 AddToReadyList(cb_and_mask); 336 AddToReadyList(cb_and_mask);
339 } 337 }
340 338
341 class TrueFalseGuard { 339 class TrueFalseGuard {
342 public: 340 public:
343 explicit TrueFalseGuard(bool* guarded_bool) : guarded_bool_(guarded_bool) { 341 explicit TrueFalseGuard(bool* guarded_bool) : guarded_bool_(guarded_bool) {
344 DCHECK(guarded_bool_ != NULL); 342 DCHECK(guarded_bool_ != NULL);
345 DCHECK(*guarded_bool_ == false); 343 DCHECK(*guarded_bool_ == false);
346 *guarded_bool_ = true; 344 *guarded_bool_ = true;
347 } 345 }
348 ~TrueFalseGuard() { 346 ~TrueFalseGuard() { *guarded_bool_ = false; }
349 *guarded_bool_ = false; 347
350 }
351 private: 348 private:
352 bool* guarded_bool_; 349 bool* guarded_bool_;
353 }; 350 };
354 351
355 void EpollServer::WaitForEventsAndExecuteCallbacks() { 352 void EpollServer::WaitForEventsAndExecuteCallbacks() {
356 if (in_wait_for_events_and_execute_callbacks_) { 353 if (in_wait_for_events_and_execute_callbacks_) {
357 LOG(DFATAL) << 354 LOG(DFATAL) << "Attempting to call WaitForEventsAndExecuteCallbacks"
358 "Attempting to call WaitForEventsAndExecuteCallbacks" 355 " when an ancestor to the current function is already"
359 " when an ancestor to the current function is already" 356 " WaitForEventsAndExecuteCallbacks!";
360 " WaitForEventsAndExecuteCallbacks!";
361 // The line below is actually tested, but in coverage mode, 357 // The line below is actually tested, but in coverage mode,
362 // we never see it. 358 // we never see it.
363 return; // COV_NF_LINE 359 return; // COV_NF_LINE
364 } 360 }
365 TrueFalseGuard recursion_guard(&in_wait_for_events_and_execute_callbacks_); 361 TrueFalseGuard recursion_guard(&in_wait_for_events_and_execute_callbacks_);
366 if (alarm_map_.empty()) { 362 if (alarm_map_.empty()) {
367 // no alarms, this is business as usual. 363 // no alarms, this is business as usual.
368 WaitForEventsAndCallHandleEvents(timeout_in_us_, 364 WaitForEventsAndCallHandleEvents(timeout_in_us_, events_, events_size_);
369 events_,
370 events_size_);
371 recorded_now_in_us_ = 0; 365 recorded_now_in_us_ = 0;
372 return; 366 return;
373 } 367 }
374 368
375 // store the 'now'. If we recomputed 'now' every iteration 369 // store the 'now'. If we recomputed 'now' every iteration
376 // down below, then we might never exit that loop-- any 370 // down below, then we might never exit that loop-- any
377 // long-running alarms might install other long-running 371 // long-running alarms might install other long-running
378 // alarms, etc. By storing it here now, we ensure that 372 // alarms, etc. By storing it here now, we ensure that
379 // a more reasonable amount of work is done here. 373 // a more reasonable amount of work is done here.
380 int64 now_in_us = NowInUsec(); 374 int64 now_in_us = NowInUsec();
381 375
382 // Get the first timeout from the alarm_map where it is 376 // Get the first timeout from the alarm_map where it is
383 // stored in absolute time. 377 // stored in absolute time.
384 int64 next_alarm_time_in_us = alarm_map_.begin()->first; 378 int64 next_alarm_time_in_us = alarm_map_.begin()->first;
385 VLOG(4) << "next_alarm_time = " << next_alarm_time_in_us 379 VLOG(4) << "next_alarm_time = " << next_alarm_time_in_us
386 << " now = " << now_in_us 380 << " now = " << now_in_us
387 << " timeout_in_us = " << timeout_in_us_; 381 << " timeout_in_us = " << timeout_in_us_;
388 382
389 int64 wait_time_in_us; 383 int64 wait_time_in_us;
390 int64 alarm_timeout_in_us = next_alarm_time_in_us - now_in_us; 384 int64 alarm_timeout_in_us = next_alarm_time_in_us - now_in_us;
391 385
392 // If the next alarm is sooner than the default timeout, or if there is no 386 // If the next alarm is sooner than the default timeout, or if there is no
393 // timeout (timeout_in_us_ == -1), wake up when the alarm should fire. 387 // timeout (timeout_in_us_ == -1), wake up when the alarm should fire.
394 // Otherwise use the default timeout. 388 // Otherwise use the default timeout.
395 if (alarm_timeout_in_us < timeout_in_us_ || timeout_in_us_ < 0) { 389 if (alarm_timeout_in_us < timeout_in_us_ || timeout_in_us_ < 0) {
396 wait_time_in_us = std::max(alarm_timeout_in_us, static_cast<int64>(0)); 390 wait_time_in_us = std::max(alarm_timeout_in_us, static_cast<int64>(0));
397 } else { 391 } else {
398 wait_time_in_us = timeout_in_us_; 392 wait_time_in_us = timeout_in_us_;
399 } 393 }
400 394
401 VLOG(4) << "wait_time_in_us = " << wait_time_in_us; 395 VLOG(4) << "wait_time_in_us = " << wait_time_in_us;
402 396
403 // wait for events. 397 // wait for events.
404 398
405 WaitForEventsAndCallHandleEvents(wait_time_in_us, 399 WaitForEventsAndCallHandleEvents(wait_time_in_us, events_, events_size_);
406 events_,
407 events_size_);
408 CallAndReregisterAlarmEvents(); 400 CallAndReregisterAlarmEvents();
409 recorded_now_in_us_ = 0; 401 recorded_now_in_us_ = 0;
410 } 402 }
411 403
412 void EpollServer::SetFDReady(int fd, int events_to_fake) { 404 void EpollServer::SetFDReady(int fd, int events_to_fake) {
413 FDToCBMap::iterator fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd)); 405 FDToCBMap::iterator fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
414 if (cb_map_.end() != fd_i && fd_i->cb != NULL) { 406 if (cb_map_.end() != fd_i && fd_i->cb != NULL) {
415 // This const_cast is necessary for LIST_HEAD_INSERT to work. Declaring 407 // This const_cast is necessary for LIST_HEAD_INSERT to work. Declaring
416 // entry mutable is insufficient because LIST_HEAD_INSERT assigns the 408 // entry mutable is insufficient because LIST_HEAD_INSERT assigns the
417 // forward pointer of the list head to the current cb_and_mask, and the 409 // forward pointer of the list head to the current cb_and_mask, and the
(...skipping 14 matching lines...) Expand all
432 424
433 void EpollServer::SetFDNotReady(int fd) { 425 void EpollServer::SetFDNotReady(int fd) {
434 FDToCBMap::iterator fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd)); 426 FDToCBMap::iterator fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
435 if (cb_map_.end() != fd_i) { 427 if (cb_map_.end() != fd_i) {
436 RemoveFromReadyList(*fd_i); 428 RemoveFromReadyList(*fd_i);
437 } 429 }
438 } 430 }
439 431
440 bool EpollServer::IsFDReady(int fd) const { 432 bool EpollServer::IsFDReady(int fd) const {
441 FDToCBMap::const_iterator fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd)); 433 FDToCBMap::const_iterator fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
442 return (cb_map_.end() != fd_i && 434 return (cb_map_.end() != fd_i && fd_i->cb != NULL &&
443 fd_i->cb != NULL &&
444 fd_i->entry.le_prev != NULL); 435 fd_i->entry.le_prev != NULL);
445 } 436 }
446 437
447 void EpollServer::VerifyReadyList() const { 438 void EpollServer::VerifyReadyList() const {
448 int count = 0; 439 int count = 0;
449 CBAndEventMask* cur = ready_list_.lh_first; 440 CBAndEventMask* cur = ready_list_.lh_first;
450 for (; cur; cur = cur->entry.le_next) { 441 for (; cur; cur = cur->entry.le_next) {
451 ++count; 442 ++count;
452 } 443 }
453 for (cur = tmp_list_.lh_first; cur; cur = cur->entry.le_next) { 444 for (cur = tmp_list_.lh_first; cur; cur = cur->entry.le_next) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 489
499 int64 EpollServer::ApproximateNowInUsec() const { 490 int64 EpollServer::ApproximateNowInUsec() const {
500 if (recorded_now_in_us_ != 0) { 491 if (recorded_now_in_us_ != 0) {
501 return recorded_now_in_us_; 492 return recorded_now_in_us_;
502 } 493 }
503 return this->NowInUsec(); 494 return this->NowInUsec();
504 } 495 }
505 496
506 std::string EpollServer::EventMaskToString(int event_mask) { 497 std::string EpollServer::EventMaskToString(int event_mask) {
507 std::string s; 498 std::string s;
508 if (event_mask & EPOLLIN) s += "EPOLLIN "; 499 if (event_mask & EPOLLIN)
509 if (event_mask & EPOLLPRI) s += "EPOLLPRI "; 500 s += "EPOLLIN ";
510 if (event_mask & EPOLLOUT) s += "EPOLLOUT "; 501 if (event_mask & EPOLLPRI)
511 if (event_mask & EPOLLRDNORM) s += "EPOLLRDNORM "; 502 s += "EPOLLPRI ";
512 if (event_mask & EPOLLRDBAND) s += "EPOLLRDBAND "; 503 if (event_mask & EPOLLOUT)
513 if (event_mask & EPOLLWRNORM) s += "EPOLLWRNORM "; 504 s += "EPOLLOUT ";
514 if (event_mask & EPOLLWRBAND) s += "EPOLLWRBAND "; 505 if (event_mask & EPOLLRDNORM)
515 if (event_mask & EPOLLMSG) s += "EPOLLMSG "; 506 s += "EPOLLRDNORM ";
516 if (event_mask & EPOLLERR) s += "EPOLLERR "; 507 if (event_mask & EPOLLRDBAND)
517 if (event_mask & EPOLLHUP) s += "EPOLLHUP "; 508 s += "EPOLLRDBAND ";
518 if (event_mask & EPOLLONESHOT) s += "EPOLLONESHOT "; 509 if (event_mask & EPOLLWRNORM)
519 if (event_mask & EPOLLET) s += "EPOLLET "; 510 s += "EPOLLWRNORM ";
511 if (event_mask & EPOLLWRBAND)
512 s += "EPOLLWRBAND ";
513 if (event_mask & EPOLLMSG)
514 s += "EPOLLMSG ";
515 if (event_mask & EPOLLERR)
516 s += "EPOLLERR ";
517 if (event_mask & EPOLLHUP)
518 s += "EPOLLHUP ";
519 if (event_mask & EPOLLONESHOT)
520 s += "EPOLLONESHOT ";
521 if (event_mask & EPOLLET)
522 s += "EPOLLET ";
520 return s; 523 return s;
521 } 524 }
522 525
523 void EpollServer::LogStateOnCrash() { 526 void EpollServer::LogStateOnCrash() {
524 LOG(ERROR) << "----------------------Epoll Server---------------------------"; 527 LOG(ERROR) << "----------------------Epoll Server---------------------------";
525 LOG(ERROR) << "Epoll server " << this << " polling on fd " << epoll_fd_; 528 LOG(ERROR) << "Epoll server " << this << " polling on fd " << epoll_fd_;
526 LOG(ERROR) << "timeout_in_us_: " << timeout_in_us_; 529 LOG(ERROR) << "timeout_in_us_: " << timeout_in_us_;
527 530
528 // Log sessions with alarms. 531 // Log sessions with alarms.
529 LOG(ERROR) << alarm_map_.size() << " alarms registered."; 532 LOG(ERROR) << alarm_map_.size() << " alarms registered.";
530 for (TimeToAlarmCBMap::iterator it = alarm_map_.begin(); 533 for (TimeToAlarmCBMap::iterator it = alarm_map_.begin();
531 it != alarm_map_.end(); 534 it != alarm_map_.end();
532 ++it) { 535 ++it) {
533 const bool skipped = 536 const bool skipped =
534 alarms_reregistered_and_should_be_skipped_.find(it->second) 537 alarms_reregistered_and_should_be_skipped_.find(it->second) !=
535 != alarms_reregistered_and_should_be_skipped_.end(); 538 alarms_reregistered_and_should_be_skipped_.end();
536 LOG(ERROR) << "Alarm " << it->second << " registered at time " << it->first 539 LOG(ERROR) << "Alarm " << it->second << " registered at time " << it->first
537 << " and should be skipped = " << skipped; 540 << " and should be skipped = " << skipped;
538 } 541 }
539 542
540 LOG(ERROR) << cb_map_.size() << " fd callbacks registered."; 543 LOG(ERROR) << cb_map_.size() << " fd callbacks registered.";
541 for (FDToCBMap::iterator it = cb_map_.begin(); 544 for (FDToCBMap::iterator it = cb_map_.begin(); it != cb_map_.end(); ++it) {
542 it != cb_map_.end();
543 ++it) {
544 LOG(ERROR) << "fd: " << it->fd << " with mask " << it->event_mask 545 LOG(ERROR) << "fd: " << it->fd << " with mask " << it->event_mask
545 << " registered with cb: " << it->cb; 546 << " registered with cb: " << it->cb;
546 } 547 }
547 LOG(ERROR) << "----------------------/Epoll Server--------------------------"; 548 LOG(ERROR) << "----------------------/Epoll Server--------------------------";
548 } 549 }
549 550
550
551
552 //////////////////////////////////////////////////////////////////////////////// 551 ////////////////////////////////////////////////////////////////////////////////
553 //////////////////////////////////////////////////////////////////////////////// 552 ////////////////////////////////////////////////////////////////////////////////
554 553
555 void EpollServer::DelFD(int fd) const { 554 void EpollServer::DelFD(int fd) const {
556 struct epoll_event ee; 555 struct epoll_event ee;
557 memset(&ee, 0, sizeof(ee)); 556 memset(&ee, 0, sizeof(ee));
558 #ifdef EPOLL_SERVER_EVENT_TRACING 557 #ifdef EPOLL_SERVER_EVENT_TRACING
559 event_recorder_.RecordFDMaskEvent(fd, 0, "DelFD"); 558 event_recorder_.RecordFDMaskEvent(fd, 0, "DelFD");
560 #endif 559 #endif
561 if (epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &ee)) { 560 if (epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &ee)) {
(...skipping 25 matching lines...) Expand all
587 //////////////////////////////////////// 586 ////////////////////////////////////////
588 587
589 void EpollServer::ModFD(int fd, int event_mask) const { 588 void EpollServer::ModFD(int fd, int event_mask) const {
590 struct epoll_event ee; 589 struct epoll_event ee;
591 memset(&ee, 0, sizeof(ee)); 590 memset(&ee, 0, sizeof(ee));
592 ee.events = event_mask | EPOLLERR | EPOLLHUP; 591 ee.events = event_mask | EPOLLERR | EPOLLHUP;
593 ee.data.fd = fd; 592 ee.data.fd = fd;
594 #ifdef EPOLL_SERVER_EVENT_TRACING 593 #ifdef EPOLL_SERVER_EVENT_TRACING
595 event_recorder_.RecordFDMaskEvent(fd, ee.events, "ModFD"); 594 event_recorder_.RecordFDMaskEvent(fd, ee.events, "ModFD");
596 #endif 595 #endif
597 VLOG(3) << "modifying fd= " << fd << " " 596 VLOG(3) << "modifying fd= " << fd << " " << EventMaskToString(ee.events);
598 << EventMaskToString(ee.events);
599 if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, fd, &ee)) { 597 if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, fd, &ee)) {
600 int saved_errno = errno; 598 int saved_errno = errno;
601 char buf[kErrorBufferSize]; 599 char buf[kErrorBufferSize];
602 LOG(FATAL) << "Epoll set modification error for fd " << fd << ": " 600 LOG(FATAL) << "Epoll set modification error for fd " << fd << ": "
603 << strerror_r(saved_errno, buf, sizeof(buf)); 601 << strerror_r(saved_errno, buf, sizeof(buf));
604 } 602 }
605 } 603 }
606 604
607 //////////////////////////////////////// 605 ////////////////////////////////////////
608 606
609 void EpollServer::ModifyFD(int fd, int remove_event, int add_event) { 607 void EpollServer::ModifyFD(int fd, int remove_event, int add_event) {
610 FDToCBMap::iterator fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd)); 608 FDToCBMap::iterator fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
611 if (cb_map_.end() == fd_i) { 609 if (cb_map_.end() == fd_i) {
612 VLOG(2) << "Didn't find the fd " << fd << "in internal structures"; 610 VLOG(2) << "Didn't find the fd " << fd << "in internal structures";
613 return; 611 return;
614 } 612 }
615 613
616 if (fd_i->cb != NULL) { 614 if (fd_i->cb != NULL) {
617 int & event_mask = fd_i->event_mask; 615 int& event_mask = fd_i->event_mask;
618 VLOG(3) << "fd= " << fd 616 VLOG(3) << "fd= " << fd
619 << " event_mask before: " << EventMaskToString(event_mask); 617 << " event_mask before: " << EventMaskToString(event_mask);
620 event_mask &= ~remove_event; 618 event_mask &= ~remove_event;
621 event_mask |= add_event; 619 event_mask |= add_event;
622 620
623 VLOG(3) << " event_mask after: " << EventMaskToString(event_mask); 621 VLOG(3) << " event_mask after: " << EventMaskToString(event_mask);
624 622
625 ModFD(fd, event_mask); 623 ModFD(fd, event_mask);
626 624
627 fd_i->cb->OnModification(fd, event_mask); 625 fd_i->cb->OnModification(fd, event_mask);
(...skipping 13 matching lines...) Expand all
641 // should set timeout_in_us to -1000 so we will 639 // should set timeout_in_us to -1000 so we will
642 // Wait(-1000/1000) == Wait(-1) == Wait forever. 640 // Wait(-1000/1000) == Wait(-1) == Wait forever.
643 timeout_in_us = -1000; 641 timeout_in_us = -1000;
644 } else { 642 } else {
645 // If timeout is specified, and the ready list is empty. 643 // If timeout is specified, and the ready list is empty.
646 if (timeout_in_us < 1000) { 644 if (timeout_in_us < 1000) {
647 timeout_in_us = 1000; 645 timeout_in_us = 1000;
648 } 646 }
649 } 647 }
650 const int timeout_in_ms = timeout_in_us / 1000; 648 const int timeout_in_ms = timeout_in_us / 1000;
651 int nfds = epoll_wait_impl(epoll_fd_, 649 int nfds = epoll_wait_impl(epoll_fd_, events, events_size, timeout_in_ms);
652 events,
653 events_size,
654 timeout_in_ms);
655 VLOG(3) << "nfds=" << nfds; 650 VLOG(3) << "nfds=" << nfds;
656 651
657 #ifdef EPOLL_SERVER_EVENT_TRACING 652 #ifdef EPOLL_SERVER_EVENT_TRACING
658 event_recorder_.RecordEpollWaitEvent(timeout_in_ms, nfds); 653 event_recorder_.RecordEpollWaitEvent(timeout_in_ms, nfds);
659 #endif 654 #endif
660 655
661 // If you're wondering why the NowInUsec() is recorded here, the answer is 656 // If you're wondering why the NowInUsec() is recorded here, the answer is
662 // simple: If we did it before the epoll_wait_impl, then the max error for 657 // simple: If we did it before the epoll_wait_impl, then the max error for
663 // the ApproximateNowInUs() call would be as large as the maximum length of 658 // the ApproximateNowInUs() call would be as large as the maximum length of
664 // epoll_wait, which can be arbitrarily long. Since this would make 659 // epoll_wait, which can be arbitrarily long. Since this would make
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 if (tmp_list_.lh_first) { 692 if (tmp_list_.lh_first) {
698 tmp_list_.lh_first->entry.le_prev = &tmp_list_.lh_first; 693 tmp_list_.lh_first->entry.le_prev = &tmp_list_.lh_first;
699 EpollEvent event(0, false); 694 EpollEvent event(0, false);
700 while (tmp_list_.lh_first != NULL) { 695 while (tmp_list_.lh_first != NULL) {
701 DCHECK_GT(ready_list_size_, 0); 696 DCHECK_GT(ready_list_size_, 0);
702 CBAndEventMask* cb_and_mask = tmp_list_.lh_first; 697 CBAndEventMask* cb_and_mask = tmp_list_.lh_first;
703 RemoveFromReadyList(*cb_and_mask); 698 RemoveFromReadyList(*cb_and_mask);
704 699
705 event.out_ready_mask = 0; 700 event.out_ready_mask = 0;
706 event.in_events = 701 event.in_events =
707 cb_and_mask->events_asserted | cb_and_mask->events_to_fake; 702 cb_and_mask->events_asserted | cb_and_mask->events_to_fake;
708 // TODO(fenix): get rid of the two separate fields in cb_and_mask. 703 // TODO(fenix): get rid of the two separate fields in cb_and_mask.
709 cb_and_mask->events_asserted = 0; 704 cb_and_mask->events_asserted = 0;
710 cb_and_mask->events_to_fake = 0; 705 cb_and_mask->events_to_fake = 0;
711 { 706 {
712 // OnEvent() may call UnRegister, so we set in_use, here. Any 707 // OnEvent() may call UnRegister, so we set in_use, here. Any
713 // UnRegister call will now simply set the cb to NULL instead of 708 // UnRegister call will now simply set the cb to NULL instead of
714 // invalidating the cb_and_mask object (by deleting the object in the 709 // invalidating the cb_and_mask object (by deleting the object in the
715 // map to which cb_and_mask refers) 710 // map to which cb_and_mask refers)
716 TrueFalseGuard in_use_guard(&(cb_and_mask->in_use)); 711 TrueFalseGuard in_use_guard(&(cb_and_mask->in_use));
717 cb_and_mask->cb->OnEvent(cb_and_mask->fd, &event); 712 cb_and_mask->cb->OnEvent(cb_and_mask->fd, &event);
(...skipping 14 matching lines...) Expand all
732 } 727 }
733 728
734 void EpollServer::CallAndReregisterAlarmEvents() { 729 void EpollServer::CallAndReregisterAlarmEvents() {
735 int64 now_in_us = recorded_now_in_us_; 730 int64 now_in_us = recorded_now_in_us_;
736 DCHECK_NE(0, recorded_now_in_us_); 731 DCHECK_NE(0, recorded_now_in_us_);
737 732
738 TimeToAlarmCBMap::iterator erase_it; 733 TimeToAlarmCBMap::iterator erase_it;
739 734
740 // execute alarms. 735 // execute alarms.
741 for (TimeToAlarmCBMap::iterator i = alarm_map_.begin(); 736 for (TimeToAlarmCBMap::iterator i = alarm_map_.begin();
742 i != alarm_map_.end(); 737 i != alarm_map_.end();) {
743 ) {
744 if (i->first > now_in_us) { 738 if (i->first > now_in_us) {
745 break; 739 break;
746 } 740 }
747 AlarmCB* cb = i->second; 741 AlarmCB* cb = i->second;
748 // Execute the OnAlarm() only if we did not register 742 // Execute the OnAlarm() only if we did not register
749 // it in this loop itself. 743 // it in this loop itself.
750 const bool added_in_this_round = 744 const bool added_in_this_round =
751 alarms_reregistered_and_should_be_skipped_.find(cb) 745 alarms_reregistered_and_should_be_skipped_.find(cb) !=
752 != alarms_reregistered_and_should_be_skipped_.end(); 746 alarms_reregistered_and_should_be_skipped_.end();
753 if (added_in_this_round) { 747 if (added_in_this_round) {
754 ++i; 748 ++i;
755 continue; 749 continue;
756 } 750 }
757 all_alarms_.erase(cb); 751 all_alarms_.erase(cb);
758 const int64 new_timeout_time_in_us = cb->OnAlarm(); 752 const int64 new_timeout_time_in_us = cb->OnAlarm();
759 753
760 erase_it = i; 754 erase_it = i;
761 ++i; 755 ++i;
762 alarm_map_.erase(erase_it); 756 alarm_map_.erase(erase_it);
763 757
764 if (new_timeout_time_in_us > 0) { 758 if (new_timeout_time_in_us > 0) {
765 // We add to hash_set only if the new timeout is <= now_in_us. 759 // We add to hash_set only if the new timeout is <= now_in_us.
766 // if timeout is > now_in_us then we have no fear that this alarm 760 // if timeout is > now_in_us then we have no fear that this alarm
767 // can be reexecuted in this loop, and hence we do not need to 761 // can be reexecuted in this loop, and hence we do not need to
768 // worry about a recursive loop. 762 // worry about a recursive loop.
769 DVLOG(3) << "Reregistering alarm " 763 DVLOG(3) << "Reregistering alarm "
770 << " " << cb 764 << " " << cb << " " << new_timeout_time_in_us << " "
771 << " " << new_timeout_time_in_us 765 << now_in_us;
772 << " " << now_in_us;
773 if (new_timeout_time_in_us <= now_in_us) { 766 if (new_timeout_time_in_us <= now_in_us) {
774 alarms_reregistered_and_should_be_skipped_.insert(cb); 767 alarms_reregistered_and_should_be_skipped_.insert(cb);
775 } 768 }
776 RegisterAlarm(new_timeout_time_in_us, cb); 769 RegisterAlarm(new_timeout_time_in_us, cb);
777 } 770 }
778 } 771 }
779 alarms_reregistered_and_should_be_skipped_.clear(); 772 alarms_reregistered_and_should_be_skipped_.clear();
780 } 773 }
781 774
782 EpollAlarm::EpollAlarm() : eps_(NULL), registered_(false) { 775 EpollAlarm::EpollAlarm() : eps_(NULL), registered_(false) {
(...skipping 28 matching lines...) Expand all
811 804
812 // If the alarm was registered, unregister it. 805 // If the alarm was registered, unregister it.
813 void EpollAlarm::UnregisterIfRegistered() { 806 void EpollAlarm::UnregisterIfRegistered() {
814 if (!registered_) { 807 if (!registered_) {
815 return; 808 return;
816 } 809 }
817 eps_->UnregisterAlarm(token_); 810 eps_->UnregisterAlarm(token_);
818 } 811 }
819 812
820 } // namespace net 813 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698