Example #1
0
// Delete a timer from the store by ID.
void TimerStore::delete_timer(TimerID id)
{
  std::map<TimerID, Timer*>::iterator it;
  it = _timer_lookup_table.find(id);
  if (it != _timer_lookup_table.end())
  {
    // The timer is still present in the store, delete it.
    Timer* timer = it->second;
    Bucket* bucket;
    size_t num_erased;

    // Delete the timer from the overdue buckets / timer wheels / heap. Try the
    // overdue bucket first, then the short wheel then the long wheel, then
    // finally the heap.
    num_erased = _overdue_timers.erase(timer);

    if (num_erased == 0)
    {
      bucket = short_wheel_bucket(timer);
      num_erased = bucket->erase(timer);

      if (num_erased == 0)
      {
        bucket = long_wheel_bucket(timer);
        num_erased = bucket->erase(timer);

        if (num_erased == 0)
        {
          std::vector<Timer*>::iterator heap_it;
          heap_it = std::find(_extra_heap.begin(), _extra_heap.end(), timer);
          if (heap_it != _extra_heap.end())
          {
            // Timer is in heap, remove it.
            _extra_heap.erase(heap_it, heap_it + 1);
            std::make_heap(_extra_heap.begin(), _extra_heap.end());
          }
          else
          {
            // We failed to remove the timer from any data structure.  Try and
            // purge the timer from all the timer wheels (we're already sure
            // that it's not in the heap).

            // LCOV_EXCL_START
            LOG_ERROR("Failed to remove timer consistently");
            purge_timer_from_wheels(timer);

            // Assert after purging, so we get a nice log detailing how the
            // purge went.
            assert(!"Failed to remove timer consistently");
            // LCOV_EXCL_STOP
          }
        }
      }
    }

    _timer_lookup_table.erase(id);
    delete timer;
  }
}