OLD | NEW |
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> |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 events_size_); | 354 events_size_); |
355 recorded_now_in_us_ = 0; | 355 recorded_now_in_us_ = 0; |
356 return; | 356 return; |
357 } | 357 } |
358 | 358 |
359 // store the 'now'. If we recomputed 'now' every iteration | 359 // store the 'now'. If we recomputed 'now' every iteration |
360 // down below, then we might never exit that loop-- any | 360 // down below, then we might never exit that loop-- any |
361 // long-running alarms might install other long-running | 361 // long-running alarms might install other long-running |
362 // alarms, etc. By storing it here now, we ensure that | 362 // alarms, etc. By storing it here now, we ensure that |
363 // a more reasonable amount of work is done here. | 363 // a more reasonable amount of work is done here. |
364 int64 now_in_us = NowInUsec(); | 364 int64_t now_in_us = NowInUsec(); |
365 | 365 |
366 // Get the first timeout from the alarm_map where it is | 366 // Get the first timeout from the alarm_map where it is |
367 // stored in absolute time. | 367 // stored in absolute time. |
368 int64 next_alarm_time_in_us = alarm_map_.begin()->first; | 368 int64_t next_alarm_time_in_us = alarm_map_.begin()->first; |
369 VLOG(4) << "next_alarm_time = " << next_alarm_time_in_us | 369 VLOG(4) << "next_alarm_time = " << next_alarm_time_in_us |
370 << " now = " << now_in_us | 370 << " now = " << now_in_us |
371 << " timeout_in_us = " << timeout_in_us_; | 371 << " timeout_in_us = " << timeout_in_us_; |
372 | 372 |
373 int64 wait_time_in_us; | 373 int64_t wait_time_in_us; |
374 int64 alarm_timeout_in_us = next_alarm_time_in_us - now_in_us; | 374 int64_t alarm_timeout_in_us = next_alarm_time_in_us - now_in_us; |
375 | 375 |
376 // If the next alarm is sooner than the default timeout, or if there is no | 376 // If the next alarm is sooner than the default timeout, or if there is no |
377 // timeout (timeout_in_us_ == -1), wake up when the alarm should fire. | 377 // timeout (timeout_in_us_ == -1), wake up when the alarm should fire. |
378 // Otherwise use the default timeout. | 378 // Otherwise use the default timeout. |
379 if (alarm_timeout_in_us < timeout_in_us_ || timeout_in_us_ < 0) { | 379 if (alarm_timeout_in_us < timeout_in_us_ || timeout_in_us_ < 0) { |
380 wait_time_in_us = std::max(alarm_timeout_in_us, static_cast<int64>(0)); | 380 wait_time_in_us = std::max(alarm_timeout_in_us, static_cast<int64_t>(0)); |
381 } else { | 381 } else { |
382 wait_time_in_us = timeout_in_us_; | 382 wait_time_in_us = timeout_in_us_; |
383 } | 383 } |
384 | 384 |
385 VLOG(4) << "wait_time_in_us = " << wait_time_in_us; | 385 VLOG(4) << "wait_time_in_us = " << wait_time_in_us; |
386 | 386 |
387 // wait for events. | 387 // wait for events. |
388 | 388 |
389 WaitForEventsAndCallHandleEvents(wait_time_in_us, | 389 WaitForEventsAndCallHandleEvents(wait_time_in_us, |
390 events_, | 390 events_, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 CBAndEventMask* cur = ready_list_.lh_first; | 433 CBAndEventMask* cur = ready_list_.lh_first; |
434 for (; cur; cur = cur->entry.le_next) { | 434 for (; cur; cur = cur->entry.le_next) { |
435 ++count; | 435 ++count; |
436 } | 436 } |
437 for (cur = tmp_list_.lh_first; cur; cur = cur->entry.le_next) { | 437 for (cur = tmp_list_.lh_first; cur; cur = cur->entry.le_next) { |
438 ++count; | 438 ++count; |
439 } | 439 } |
440 CHECK_EQ(ready_list_size_, count) << "Ready list size does not match count"; | 440 CHECK_EQ(ready_list_size_, count) << "Ready list size does not match count"; |
441 } | 441 } |
442 | 442 |
443 void EpollServer::RegisterAlarm(int64 timeout_time_in_us, AlarmCB* ac) { | 443 void EpollServer::RegisterAlarm(int64_t timeout_time_in_us, AlarmCB* ac) { |
444 CHECK(ac); | 444 CHECK(ac); |
445 if (ContainsKey(all_alarms_, ac)) { | 445 if (ContainsKey(all_alarms_, ac)) { |
446 LOG(FATAL) << "Alarm already exists " << ac; | 446 LOG(FATAL) << "Alarm already exists " << ac; |
447 } | 447 } |
448 VLOG(4) << "RegisteringAlarm at : " << timeout_time_in_us; | 448 VLOG(4) << "RegisteringAlarm at : " << timeout_time_in_us; |
449 | 449 |
450 TimeToAlarmCBMap::iterator alarm_iter = | 450 TimeToAlarmCBMap::iterator alarm_iter = |
451 alarm_map_.insert(std::make_pair(timeout_time_in_us, ac)); | 451 alarm_map_.insert(std::make_pair(timeout_time_in_us, ac)); |
452 | 452 |
453 all_alarms_.insert(ac); | 453 all_alarms_.insert(ac); |
(...skipping 15 matching lines...) Expand all Loading... |
469 // Omit the internal FD (read_fd_) | 469 // Omit the internal FD (read_fd_) |
470 return cb_map_.size() - 1; | 470 return cb_map_.size() - 1; |
471 } | 471 } |
472 | 472 |
473 void EpollServer::Wake() { | 473 void EpollServer::Wake() { |
474 char data = 'd'; // 'd' is for data. It's good enough for me. | 474 char data = 'd'; // 'd' is for data. It's good enough for me. |
475 int rv = write(write_fd_, &data, 1); | 475 int rv = write(write_fd_, &data, 1); |
476 DCHECK_EQ(rv, 1); | 476 DCHECK_EQ(rv, 1); |
477 } | 477 } |
478 | 478 |
479 int64 EpollServer::NowInUsec() const { | 479 int64_t EpollServer::NowInUsec() const { |
480 return (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds(); | 480 return (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds(); |
481 } | 481 } |
482 | 482 |
483 int64 EpollServer::ApproximateNowInUsec() const { | 483 int64_t EpollServer::ApproximateNowInUsec() const { |
484 if (recorded_now_in_us_ != 0) { | 484 if (recorded_now_in_us_ != 0) { |
485 return recorded_now_in_us_; | 485 return recorded_now_in_us_; |
486 } | 486 } |
487 return this->NowInUsec(); | 487 return this->NowInUsec(); |
488 } | 488 } |
489 | 489 |
490 std::string EpollServer::EventMaskToString(int event_mask) { | 490 std::string EpollServer::EventMaskToString(int event_mask) { |
491 std::string s; | 491 std::string s; |
492 if (event_mask & EPOLLIN) s += "EPOLLIN "; | 492 if (event_mask & EPOLLIN) s += "EPOLLIN "; |
493 if (event_mask & EPOLLPRI) s += "EPOLLPRI "; | 493 if (event_mask & EPOLLPRI) s += "EPOLLPRI "; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 event_mask |= add_event; | 605 event_mask |= add_event; |
606 | 606 |
607 VLOG(3) << " event_mask after: " << EventMaskToString(event_mask); | 607 VLOG(3) << " event_mask after: " << EventMaskToString(event_mask); |
608 | 608 |
609 ModFD(fd, event_mask); | 609 ModFD(fd, event_mask); |
610 | 610 |
611 fd_i->cb->OnModification(fd, event_mask); | 611 fd_i->cb->OnModification(fd, event_mask); |
612 } | 612 } |
613 } | 613 } |
614 | 614 |
615 void EpollServer::WaitForEventsAndCallHandleEvents(int64 timeout_in_us, | 615 void EpollServer::WaitForEventsAndCallHandleEvents(int64_t timeout_in_us, |
616 struct epoll_event events[], | 616 struct epoll_event events[], |
617 int events_size) { | 617 int events_size) { |
618 if (timeout_in_us == 0 || ready_list_.lh_first != NULL) { | 618 if (timeout_in_us == 0 || ready_list_.lh_first != NULL) { |
619 // If ready list is not empty, then don't sleep at all. | 619 // If ready list is not empty, then don't sleep at all. |
620 timeout_in_us = 0; | 620 timeout_in_us = 0; |
621 } else if (timeout_in_us < 0) { | 621 } else if (timeout_in_us < 0) { |
622 LOG(INFO) << "Negative epoll timeout: " << timeout_in_us | 622 LOG(INFO) << "Negative epoll timeout: " << timeout_in_us |
623 << "us; epoll will wait forever for events."; | 623 << "us; epoll will wait forever for events."; |
624 // If timeout_in_us is < 0 we are supposed to Wait forever. This means we | 624 // If timeout_in_us is < 0 we are supposed to Wait forever. This means we |
625 // should set timeout_in_us to -1000 so we will | 625 // should set timeout_in_us to -1000 so we will |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 } else if (event.out_ready_mask != 0) { | 709 } else if (event.out_ready_mask != 0) { |
710 cb_and_mask->events_to_fake = event.out_ready_mask; | 710 cb_and_mask->events_to_fake = event.out_ready_mask; |
711 AddToReadyList(cb_and_mask); | 711 AddToReadyList(cb_and_mask); |
712 } | 712 } |
713 } | 713 } |
714 } | 714 } |
715 DCHECK(tmp_list_.lh_first == NULL); | 715 DCHECK(tmp_list_.lh_first == NULL); |
716 } | 716 } |
717 | 717 |
718 void EpollServer::CallAndReregisterAlarmEvents() { | 718 void EpollServer::CallAndReregisterAlarmEvents() { |
719 int64 now_in_us = recorded_now_in_us_; | 719 int64_t now_in_us = recorded_now_in_us_; |
720 DCHECK_NE(0, recorded_now_in_us_); | 720 DCHECK_NE(0, recorded_now_in_us_); |
721 | 721 |
722 TimeToAlarmCBMap::iterator erase_it; | 722 TimeToAlarmCBMap::iterator erase_it; |
723 | 723 |
724 // execute alarms. | 724 // execute alarms. |
725 for (TimeToAlarmCBMap::iterator i = alarm_map_.begin(); | 725 for (TimeToAlarmCBMap::iterator i = alarm_map_.begin(); |
726 i != alarm_map_.end(); | 726 i != alarm_map_.end(); |
727 ) { | 727 ) { |
728 if (i->first > now_in_us) { | 728 if (i->first > now_in_us) { |
729 break; | 729 break; |
730 } | 730 } |
731 AlarmCB* cb = i->second; | 731 AlarmCB* cb = i->second; |
732 // Execute the OnAlarm() only if we did not register | 732 // Execute the OnAlarm() only if we did not register |
733 // it in this loop itself. | 733 // it in this loop itself. |
734 const bool added_in_this_round = | 734 const bool added_in_this_round = |
735 alarms_reregistered_and_should_be_skipped_.find(cb) | 735 alarms_reregistered_and_should_be_skipped_.find(cb) |
736 != alarms_reregistered_and_should_be_skipped_.end(); | 736 != alarms_reregistered_and_should_be_skipped_.end(); |
737 if (added_in_this_round) { | 737 if (added_in_this_round) { |
738 ++i; | 738 ++i; |
739 continue; | 739 continue; |
740 } | 740 } |
741 all_alarms_.erase(cb); | 741 all_alarms_.erase(cb); |
742 const int64 new_timeout_time_in_us = cb->OnAlarm(); | 742 const int64_t new_timeout_time_in_us = cb->OnAlarm(); |
743 | 743 |
744 erase_it = i; | 744 erase_it = i; |
745 ++i; | 745 ++i; |
746 alarm_map_.erase(erase_it); | 746 alarm_map_.erase(erase_it); |
747 | 747 |
748 if (new_timeout_time_in_us > 0) { | 748 if (new_timeout_time_in_us > 0) { |
749 // We add to hash_set only if the new timeout is <= now_in_us. | 749 // We add to hash_set only if the new timeout is <= now_in_us. |
750 // if timeout is > now_in_us then we have no fear that this alarm | 750 // if timeout is > now_in_us then we have no fear that this alarm |
751 // can be reexecuted in this loop, and hence we do not need to | 751 // can be reexecuted in this loop, and hence we do not need to |
752 // worry about a recursive loop. | 752 // worry about a recursive loop. |
(...skipping 10 matching lines...) Expand all Loading... |
763 alarms_reregistered_and_should_be_skipped_.clear(); | 763 alarms_reregistered_and_should_be_skipped_.clear(); |
764 } | 764 } |
765 | 765 |
766 EpollAlarm::EpollAlarm() : eps_(NULL), registered_(false) { | 766 EpollAlarm::EpollAlarm() : eps_(NULL), registered_(false) { |
767 } | 767 } |
768 | 768 |
769 EpollAlarm::~EpollAlarm() { | 769 EpollAlarm::~EpollAlarm() { |
770 UnregisterIfRegistered(); | 770 UnregisterIfRegistered(); |
771 } | 771 } |
772 | 772 |
773 int64 EpollAlarm::OnAlarm() { | 773 int64_t EpollAlarm::OnAlarm() { |
774 registered_ = false; | 774 registered_ = false; |
775 return 0; | 775 return 0; |
776 } | 776 } |
777 | 777 |
778 void EpollAlarm::OnRegistration(const EpollServer::AlarmRegToken& token, | 778 void EpollAlarm::OnRegistration(const EpollServer::AlarmRegToken& token, |
779 EpollServer* eps) { | 779 EpollServer* eps) { |
780 DCHECK_EQ(false, registered_); | 780 DCHECK_EQ(false, registered_); |
781 | 781 |
782 token_ = token; | 782 token_ = token; |
783 eps_ = eps; | 783 eps_ = eps; |
(...skipping 11 matching lines...) Expand all Loading... |
795 | 795 |
796 // If the alarm was registered, unregister it. | 796 // If the alarm was registered, unregister it. |
797 void EpollAlarm::UnregisterIfRegistered() { | 797 void EpollAlarm::UnregisterIfRegistered() { |
798 if (!registered_) { | 798 if (!registered_) { |
799 return; | 799 return; |
800 } | 800 } |
801 eps_->UnregisterAlarm(token_); | 801 eps_->UnregisterAlarm(token_); |
802 } | 802 } |
803 | 803 |
804 } // namespace net | 804 } // namespace net |
OLD | NEW |