MXS-1754 Use std::multimap instead of std::priority_queue
When canceling, a DelayedCall instance must be removed from the collection holding all delayed calls. Consequently priority_queue cannot be used as it 1) does not provide access to the underlying collection and 2) the underlying collection (vector or deque) is a bad choise if items in the middle needs to be removed.
This commit is contained in:
@ -13,9 +13,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <maxscale/cppdefs.hh>
|
#include <maxscale/cppdefs.hh>
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <queue>
|
|
||||||
#include <vector>
|
|
||||||
#include <maxscale/platform.h>
|
#include <maxscale/platform.h>
|
||||||
#include <maxscale/session.h>
|
#include <maxscale/session.h>
|
||||||
#include <maxscale/utils.hh>
|
#include <maxscale/utils.hh>
|
||||||
@ -1298,7 +1297,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef DelegatingTimer<Worker> PrivateTimer;
|
typedef DelegatingTimer<Worker> PrivateTimer;
|
||||||
typedef std::priority_queue<DelayedCall*, std::vector<DelayedCall*>, LaterAt> DelayedCalls;
|
typedef std::multimap<int64_t, DelayedCall*> DelayedCalls;
|
||||||
|
|
||||||
STATISTICS m_statistics; /*< Worker statistics. */
|
STATISTICS m_statistics; /*< Worker statistics. */
|
||||||
MessageQueue* m_pQueue; /*< The message queue of the worker. */
|
MessageQueue* m_pQueue; /*< The message queue of the worker. */
|
||||||
@ -1311,7 +1310,6 @@ private:
|
|||||||
Load m_load; /*< The worker load. */
|
Load m_load; /*< The worker load. */
|
||||||
PrivateTimer* m_pTimer; /*< The worker's own timer. */
|
PrivateTimer* m_pTimer; /*< The worker's own timer. */
|
||||||
DelayedCalls m_delayed_calls; /*< Current delayed calls. */
|
DelayedCalls m_delayed_calls; /*< Current delayed calls. */
|
||||||
uint64_t m_last_delayed_call; /*< When was the last delayed call made. */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1133,12 +1133,13 @@ void Worker::tick()
|
|||||||
|
|
||||||
vector<DelayedCall*> repeating_calls;
|
vector<DelayedCall*> repeating_calls;
|
||||||
|
|
||||||
DelayedCall* pDelayed_call;
|
auto i = m_delayed_calls.begin();
|
||||||
|
|
||||||
while (!m_delayed_calls.empty() && (m_delayed_calls.top()->at() <= now))
|
while ((i != m_delayed_calls.end()) && (i->first <= now))
|
||||||
{
|
{
|
||||||
pDelayed_call = m_delayed_calls.top();
|
DelayedCall* pDelayed_call = i->second;
|
||||||
m_delayed_calls.pop();
|
|
||||||
|
m_delayed_calls.erase(i++);
|
||||||
|
|
||||||
if (pDelayed_call->call(Worker::Call::EXECUTE))
|
if (pDelayed_call->call(Worker::Call::EXECUTE))
|
||||||
{
|
{
|
||||||
@ -1152,7 +1153,9 @@ void Worker::tick()
|
|||||||
|
|
||||||
for (auto i = repeating_calls.begin(); i != repeating_calls.end(); ++i)
|
for (auto i = repeating_calls.begin(); i != repeating_calls.end(); ++i)
|
||||||
{
|
{
|
||||||
m_delayed_calls.push(*i);
|
DelayedCall* pCall = *i;
|
||||||
|
|
||||||
|
m_delayed_calls.insert(std::make_pair(pCall->at(), pCall));
|
||||||
}
|
}
|
||||||
|
|
||||||
adjust_timer();
|
adjust_timer();
|
||||||
@ -1164,18 +1167,18 @@ void Worker::add_delayed_call(DelayedCall* pDelayed_call)
|
|||||||
|
|
||||||
if (!m_delayed_calls.empty())
|
if (!m_delayed_calls.empty())
|
||||||
{
|
{
|
||||||
DelayedCall* pTop = m_delayed_calls.top();
|
DelayedCall* pFirst = m_delayed_calls.begin()->second;
|
||||||
|
|
||||||
if (pDelayed_call->at() < pTop->at())
|
if (pDelayed_call->at() > pFirst->at())
|
||||||
{
|
{
|
||||||
// If the added delayed call needs to be called sooner
|
// If the added delayed call needs to be called later
|
||||||
// than the top-most delayed call, then we must adjust
|
// than the first delayed call, then we do not need to
|
||||||
// the timer.
|
// adjust the timer.
|
||||||
adjust = true;
|
adjust = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_delayed_calls.push(pDelayed_call);
|
m_delayed_calls.insert(std::make_pair(pDelayed_call->at(), pDelayed_call));
|
||||||
|
|
||||||
if (adjust)
|
if (adjust)
|
||||||
{
|
{
|
||||||
@ -1187,7 +1190,7 @@ void Worker::adjust_timer()
|
|||||||
{
|
{
|
||||||
if (!m_delayed_calls.empty())
|
if (!m_delayed_calls.empty())
|
||||||
{
|
{
|
||||||
DelayedCall* pNext_call = m_delayed_calls.top();
|
DelayedCall* pNext_call = m_delayed_calls.begin()->second;
|
||||||
|
|
||||||
uint64_t now = get_current_time_ms();
|
uint64_t now = get_current_time_ms();
|
||||||
int64_t delay = pNext_call->at() - now;
|
int64_t delay = pNext_call->at() - now;
|
||||||
|
|||||||
Reference in New Issue
Block a user