Commit 7c929b25 authored by Kirill Smelkov's avatar Kirill Smelkov

time: Switch Timer/Ticker channels from chan() -> chan(dtype='C.double')

This will allow to use the channels in nogil mode including in followup
patches touching time.pyx codebase.
parent 149ae661
...@@ -26,7 +26,7 @@ from golang cimport sync ...@@ -26,7 +26,7 @@ from golang cimport sync
from libc.math cimport INFINITY from libc.math cimport INFINITY
from cython cimport final from cython cimport final
from golang import go as pygo, select as pyselect, default as pydefault, nilchan as pynilchan, panic as pypanic from golang import go as pygo, select as pyselect, default as pydefault, panic as pypanic
def pynow(): # -> t def pynow(): # -> t
...@@ -43,10 +43,10 @@ def pysleep(double dt): ...@@ -43,10 +43,10 @@ def pysleep(double dt):
# tick returns channel connected to dt ticker. # tick returns channel connected to dt ticker.
# #
# Note: there is no way to stop created ticker. # Note: there is no way to stop created ticker.
# Note: for dt <= 0, contrary to Ticker, tick returns nilchan instead of panicking. # Note: for dt <= 0, contrary to Ticker, tick returns nil channel instead of panicking.
def tick(double dt): # -> chan time def tick(double dt): # -> chan time
if dt <= 0: if dt <= 0:
return pynilchan return pychan._nil('C.double')
return Ticker(dt).c return Ticker(dt).c
# after returns channel connected to dt timer. # after returns channel connected to dt timer.
...@@ -69,7 +69,7 @@ def after_func(double dt, f): # -> Timer ...@@ -69,7 +69,7 @@ def after_func(double dt, f): # -> Timer
# Ticking can be canceled via .stop() . # Ticking can be canceled via .stop() .
@final @final
cdef class Ticker: cdef class Ticker:
cdef readonly pychan c cdef readonly pychan c # chan[double]
cdef double _dt cdef double _dt
cdef sync.Mutex _mu cdef sync.Mutex _mu
...@@ -78,7 +78,7 @@ cdef class Ticker: ...@@ -78,7 +78,7 @@ cdef class Ticker:
def __init__(Ticker self, double dt): def __init__(Ticker self, double dt):
if dt <= 0: if dt <= 0:
pypanic("ticker: dt <= 0") pypanic("ticker: dt <= 0")
self.c = pychan(1) # 1-buffer -- same as in Go self.c = pychan(1, dtype='C.double') # 1-buffer -- same as in Go
self._dt = dt self._dt = dt
self._stop = False self._stop = False
pygo(self._tick) pygo(self._tick)
...@@ -131,7 +131,8 @@ cdef class Timer: ...@@ -131,7 +131,8 @@ cdef class Timer:
def __init__(Timer self, double dt, f=None): def __init__(Timer self, double dt, f=None):
self._f = f self._f = f
self.c = pychan(1) if f is None else pynilchan self.c = pychan(1, dtype='C.double') if f is None else \
pychan._nil('C.double')
self._dt = INFINITY self._dt = INFINITY
self._ver = 0 self._ver = 0
self.reset(dt) self.reset(dt)
......
...@@ -42,6 +42,28 @@ def test_now(): ...@@ -42,6 +42,28 @@ def test_now():
assert t3 < t4 assert t3 < t4
# test_{timer,ticker}_time verifie that Timer/Ticker, when they fire, send current time.
def test_timer_time():
Tstart = time.now()
t = time.Timer(3*dt)
tnow = t.c.recv()
Tend = time.now()
assert type(tnow) is type(Tstart)
assert Tstart < tnow < Tend
assert ((tnow - Tstart) / dt) >= 3
def test_ticker_time():
Tstart = time.now()
tx = time.Ticker(3*dt)
tnow = tx.c.recv()
Tend = time.now()
assert type(tnow) is type(Tstart)
assert Tstart < tnow < Tend
assert ((tnow - Tstart) / dt) >= 3
# test_timer verifies that Timer/Ticker fire as expected. # test_timer verifies that Timer/Ticker fire as expected.
def test_timer(): def test_timer():
# start timers at x5, x7 and x11 intervals an verify that the timers fire # start timers at x5, x7 and x11 intervals an verify that the timers fire
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment