single-shot timers are not always cancelled after cancel(), see #2903

- if the timer expired before cancel(), then isCancelled shall not
  return true
- recurring timers are not changed, because there isExpired does not
  really make sense

- [ ] backport to 2.1