diff options
author | Steve Huston <shuston@riverace.com> | 2018-06-26 19:26:49 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-26 19:26:49 -0400 |
commit | 29cc7e3b67270ef74747edda70bead9ee46cbabe (patch) | |
tree | cd66c43713fdd08738e78ce61ed9d2cfb45c197a | |
parent | 25f5307a46b10ebe7f26f46c006892f0e249c365 (diff) | |
parent | d3bb3163e9380bc55a4a8b7877949fdca5326571 (diff) | |
download | ATCD-29cc7e3b67270ef74747edda70bead9ee46cbabe.tar.gz |
Merge pull request #647 from DOCGroup/timer_wheel_coverity_fixes
Timer wheel coverity fixes
-rw-r--r-- | ACE/ace/Timer_Wheel_T.cpp | 63 | ||||
-rw-r--r-- | ACE/ace/Timer_Wheel_T.h | 2 |
2 files changed, 22 insertions, 43 deletions
diff --git a/ACE/ace/Timer_Wheel_T.cpp b/ACE/ace/Timer_Wheel_T.cpp index e9d4f294e97..7fd6f68f6bd 100644 --- a/ACE/ace/Timer_Wheel_T.cpp +++ b/ACE/ace/Timer_Wheel_T.cpp @@ -328,7 +328,14 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::generate_timer_id (u_in // This field is used as a counter instead of a timer_id. long cnt = root->get_timer_id (); - if (cnt >= max_cnt && root == root->get_next ()) + if (cnt < max_cnt) + { + root->set_timer_id (cnt + 1); + return (cnt << this->spoke_bits_) | spoke; + } + + // Count has overflowed its range. + if (root == root->get_next ()) { // Special case when we overflow on an empty spoke. We can just // wrap the count around without searching for duplicates. We only @@ -337,50 +344,20 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::generate_timer_id (u_in root->set_timer_id (1); return spoke; } - else if (cnt >= max_cnt) - { // overflow - cnt = 0; // try again starting at zero - } - else if (next_cnt == 0 || cnt < next_cnt) - { - root->set_timer_id (cnt + 1); - return (cnt << this->spoke_bits_) | spoke; - } + // Overflowed count, and the spoke is not empty. Search for an unused + // id value. //ACELIB_ERROR((LM_ERROR, "Timer id overflow. We have to search now.\n")); - - // We've run out of consecutive id numbers so now we have to search - // for a unique id. - // We'll try increasing numbers until we find one that is not in use, - // and we'll record the next highest number so that we can avoid this - // search as often as possible. - for (; cnt < max_cnt - 1; ++cnt) + for (cnt = 0; cnt < max_cnt - 1; ++cnt) { + // Look for an unused id. Yes, every new id on this spoke will result in a + // scan until all the spoke's timers get canceled/expired then the spoke will + // start over like new. So, when an empty spot is found, don't reset the + // root node's timer_id - it stays at max until the spoke clears out and + // starts over. long id = (cnt << this->spoke_bits_) | spoke; - ACE_Timer_Node_T<TYPE>* n = this->find_spoke_node (spoke, id); - if (n == 0) - { - root->set_timer_id (cnt + 1); - // Now we need to find the next highest cnt in use - next_cnt = 0; - for (; n != root; n = n->get_next ()) - { - long tmp = n->get_timer_id () >> this->spoke_bits_; - if (tmp > cnt && (tmp < next_cnt || next_cnt == 0)) - next_cnt = tmp; - } -#if defined (ACE_WIN64) - // The cast below is legit... we know we're storing a long in - // a pointer, but are only using it as a 'long' storage area. -# pragma warning(push) -# pragma warning(disable : 4312) -#endif /* ACE_WIN64 */ - root->set_act (reinterpret_cast<void*> (next_cnt)); -#if defined (ACE_WIN64) -# pragma warning(pop) -#endif /* ACE_WIN64 */ - return id; - } + if (0 == this->find_spoke_node (spoke, id)) + return id; } return -1; // We did our best, but the spoke is full. @@ -421,6 +398,10 @@ ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::schedule_i (const TYPE& n->set (type, act, future_time, interval, 0, 0, id); this->schedule_i (n, spoke, future_time); } + else + { + this->free_node (n); + } return id; } diff --git a/ACE/ace/Timer_Wheel_T.h b/ACE/ace/Timer_Wheel_T.h index 22c204ca1ef..51df3401f15 100644 --- a/ACE/ace/Timer_Wheel_T.h +++ b/ACE/ace/Timer_Wheel_T.h @@ -200,8 +200,6 @@ private: u_int spoke_count_; /// Number of timer_id bits used for the spoke int spoke_bits_; - /// Maximum number of timers per spoke - u_int max_per_spoke_; /// Resolution (in microsoconds) of the timing wheel. int res_bits_; /// Index of the list with the earliest time |