void RunLoop::AddTimer(TimerPtr timer)
{
    StackLock lock(_listLock);
    if ( ContainsTimer(timer) )
        return;
    
    _timers.push_back(timer);
    _timers.sort();
    
    if ( _waiting && _waitingUntilTimer != nullptr && _waitingUntilTimer->GetNextFireDate() < timer->GetNextFireDate() )
    {
        // signal a Run() invocation that it needs to adjust its timeout to the fire
        // date of this new timer
        WakeUp();
    }
}