Source code for uv.timer

# -*- coding: utf-8 -*-
#
# Copyright (C) 2015, Maximilian Köhl <mail@koehlma.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from __future__ import print_function, unicode_literals, division

from .library import ffi, lib, detach, dummy_callback

from .error import UVError, HandleClosedError
from .handle import HandleType, Handle

__all__ = ['Timer']


@ffi.callback('uv_timer_cb')
def uv_timer_cb(uv_timer):
    timer = detach(uv_timer)
    with timer.loop.callback_context:
        timer.on_timeout(timer)


@HandleType.TIMER
[docs]class Timer(Handle): """ Timer handles are used to schedule callbacks to be called in the future. :raises uv.UVError: error during the initialization of the handle :param loop: event loop which should be used for the handle :param callback: callback which should be called on timeout :type loop: Loop :type callback: (uv.Timer) -> None """ __slots__ = ['uv_timer', 'callback'] def __init__(self, loop=None, callback=None): self.uv_timer = ffi.new('uv_timer_t*') super(Timer, self).__init__(self.uv_timer, loop) self.callback = callback or dummy_callback """ Callback which should be called on timeout. .. function:: callback(Timer-Handle) :readonly: False :type: (uv.Timer) -> None """ code = lib.uv_timer_init(self.loop.uv_loop, self.uv_timer) if code < 0: self.destroy() raise UVError(code) @property def repeat(self): """ The repeat interval value in milliseconds. The timer will be scheduled to run on the given interval, regardless of the callback execution duration, and will follow normal timer semantics in the case of time-slice overrun. For example, if a 50ms repeating timer first runs for 17ms, it will be scheduled to run again 33ms later. If other tasks consume more than the 33ms following the first timer callback, then the callback will run as soon as possible. .. note:: If the repeat value is set from a timer callback it does not immediately take effect. If the timer was non-repeating before, it will have been stopped. If it was repeating, then the old repeat value will have been used to schedule the next timeout. :raises uv.HandleClosedError: handle has already been closed or is closing :readonly: False :rtype: int """ if self.closing: raise HandleClosedError() return lib.uv_timer_get_repeat(self.uv_timer) @repeat.setter def repeat(self, repeat): """ :raises uv.HandleClosedError: handle has already been closed or is closing :param repeat: repeat interval which should be set :type repeat: int """ if self.closing: raise HandleClosedError() lib.uv_timer_set_repeat(self.uv_timer, repeat)
[docs] def again(self): """ Stop the timer, and if it is repeating restart it using the repeat value as the timeout. If the timer has never been started before it raises :class:`uv.UVError` with :class:`uv.StatusCode.EINVAL`. :raises uv.UVError: error while restarting the timer :raises uv.HandleClosedError: handle has already been closed or is closing """ if self.closing: raise HandleClosedError code = lib.uv_timer_again(self.uv_timer) if code < 0: raise UVError(code)
[docs] def start(self, timeout, callback=None, repeat=0): """ Starts the timer. If `timeout` is zero, the callback fires on the next event loop iteration. If repeat is non-zero, the callback fires first after `timeout` milliseconds and then repeatedly after `repeat` milliseconds. :raises uv.UVError: error while starting the handle :raises uv.HandleClosedError: handle has already been closed or is closing :param timeout: timeout which should be used (in milliseconds) :param callback: callback which should be called on timeout :param repeat: repeat interval which should be set (in milliseconds) :type timeout: int :type callback: (uv.Timer) -> None :type repeat: int """ if self.closing: raise HandleClosedError() self.callback = callback or self.callback code = lib.uv_timer_start(self.uv_timer, uv_timer_cb, timeout, repeat) if code < 0: raise UVError(code)
[docs] def stop(self): """ Stops the handle, the callback will no longer be called. :raises uv.UVError: error while stopping the handle """ if self.closing: return code = lib.uv_timer_stop(self.uv_timer) if code < 0: raise UVError(code)