TimeoutQueue.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * Copyright 2011-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <folly/TimeoutQueue.h>
  17. #include <algorithm>
  18. #include <vector>
  19. namespace folly {
  20. TimeoutQueue::Id
  21. TimeoutQueue::add(int64_t now, int64_t delay, Callback callback) {
  22. Id id = nextId_++;
  23. timeouts_.insert({id, now + delay, -1, std::move(callback)});
  24. return id;
  25. }
  26. TimeoutQueue::Id
  27. TimeoutQueue::addRepeating(int64_t now, int64_t interval, Callback callback) {
  28. Id id = nextId_++;
  29. timeouts_.insert({id, now + interval, interval, std::move(callback)});
  30. return id;
  31. }
  32. int64_t TimeoutQueue::nextExpiration() const {
  33. return (
  34. timeouts_.empty() ? std::numeric_limits<int64_t>::max()
  35. : timeouts_.get<BY_EXPIRATION>().begin()->expiration);
  36. }
  37. bool TimeoutQueue::erase(Id id) {
  38. return timeouts_.get<BY_ID>().erase(id);
  39. }
  40. int64_t TimeoutQueue::runInternal(int64_t now, bool onceOnly) {
  41. auto& byExpiration = timeouts_.get<BY_EXPIRATION>();
  42. int64_t nextExp;
  43. do {
  44. const auto end = byExpiration.upper_bound(now);
  45. std::vector<Event> expired;
  46. std::move(byExpiration.begin(), end, std::back_inserter(expired));
  47. byExpiration.erase(byExpiration.begin(), end);
  48. for (const auto& event : expired) {
  49. // Reinsert if repeating, do this before executing callbacks
  50. // so the callbacks have a chance to call erase
  51. if (event.repeatInterval >= 0) {
  52. timeouts_.insert({event.id,
  53. now + event.repeatInterval,
  54. event.repeatInterval,
  55. event.callback});
  56. }
  57. }
  58. // Call callbacks
  59. for (const auto& event : expired) {
  60. event.callback(event.id, now);
  61. }
  62. nextExp = nextExpiration();
  63. } while (!onceOnly && nextExp <= now);
  64. return nextExp;
  65. }
  66. } // namespace folly