Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
pygolang
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
pygolang
Commits
873cf8aa
Commit
873cf8aa
authored
Nov 06, 2019
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
time.pyx: Use Go style for self
Ticker: self -> pytx Timer: self -> pyt
parent
a0ba1226
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
59 additions
and
59 deletions
+59
-59
_time.pyx
golang/_time.pyx
+59
-59
No files found.
golang/_time.pyx
View file @
873cf8aa
...
...
@@ -75,45 +75,45 @@ cdef class PyTicker:
cdef sync.Mutex _mu
cdef bint __stop
def __init__(PyTicker
self
, double dt):
def __init__(PyTicker
pytx
, double dt):
if dt <= 0:
pypanic("ticker: dt <= 0")
self
.c = pychan(1, dtype='C.double') # 1-buffer -- same as in Go
self
._dt = dt
self
.__stop = False
pytx
.c = pychan(1, dtype='C.double') # 1-buffer -- same as in Go
pytx
._dt = dt
pytx
.__stop = False
nogilready = pychan(dtype='C.structZ')
pygo(
self.__tick, self
, nogilready)
pygo(
pytx.__tick, pytx
, nogilready)
nogilready.recv()
# stop cancels the ticker.
#
# It is guaranteed that ticker channel is empty after stop completes.
def stop(PyTicker
self
):
_Ticker_stop_pyexc(
self
)
cdef void _stop(PyTicker
self
) nogil:
c =
self
.c.chan_double()
def stop(PyTicker
pytx
):
_Ticker_stop_pyexc(
pytx
)
cdef void _stop(PyTicker
pytx
) nogil:
c =
pytx
.c.chan_double()
self
._mu.lock()
self
.__stop = True
pytx
._mu.lock()
pytx
.__stop = True
# drain what __tick could have been queued already
while c.len() > 0:
c.recv()
self
._mu.unlock()
pytx
._mu.unlock()
cdef void __tick(PyTicker
self
, pychan nogilready) except +topyexc:
cdef void __tick(PyTicker
pytx
, pychan nogilready) except +topyexc:
with nogil:
nogilready.chan_structZ().close()
self
.___tick()
cdef void ___tick(PyTicker
self
) nogil:
c =
self
.c.chan_double()
pytx
.___tick()
cdef void ___tick(PyTicker
pytx
) nogil:
c =
pytx
.c.chan_double()
while 1:
# XXX adjust for accumulated error δ?
sleep(
self
._dt)
sleep(
pytx
._dt)
self
._mu.lock()
if
self
.__stop:
self
._mu.unlock()
pytx
._mu.lock()
if
pytx
.__stop:
pytx
._mu.unlock()
return
# send from under ._mu so that .stop can be sure there is no
...
...
@@ -123,7 +123,7 @@ cdef class PyTicker:
default,
c.sends(&t),
])
self
._mu.unlock()
pytx
._mu.unlock()
# Timer arranges for time event to be sent to .c channel after dt time.
...
...
@@ -141,13 +141,13 @@ cdef class PyTimer:
cdef double _dt # +inf - stopped, otherwise - armed
cdef int _ver # current timer was armed by n'th reset
def __init__(PyTimer
self
, double dt, f=None):
self._f
= f
self.c
= pychan(1, dtype='C.double') if f is None else \
pychan._nil('C.double')
self._dt
= INFINITY
self._ver
= 0
self
.reset(dt)
def __init__(PyTimer
pyt
, double dt, f=None):
pyt._f
= f
pyt.c
= pychan(1, dtype='C.double') if f is None else \
pychan._nil('C.double')
pyt._dt
= INFINITY
pyt._ver
= 0
pyt
.reset(dt)
# stop cancels the timer.
#
...
...
@@ -162,76 +162,76 @@ cdef class PyTimer:
# Note: similarly to Go, if Timer is used with function - it is not
# guaranteed that after stop the function is not running - in such case
# the caller must explicitly synchronize with that function to complete.
def stop(PyTimer
self
): # -> canceled
return _Timer_stop_pyexc(
self
)
cdef bint _stop(PyTimer
self
) nogil: # -> canceled
def stop(PyTimer
pyt
): # -> canceled
return _Timer_stop_pyexc(
pyt
)
cdef bint _stop(PyTimer
pyt
) nogil: # -> canceled
cdef bint canceled
c =
self
.c.chan_double()
c =
pyt
.c.chan_double()
self
._mu.lock()
pyt
._mu.lock()
if
self
._dt == INFINITY:
if
pyt
._dt == INFINITY:
canceled = False
else:
self
._dt = INFINITY
self
._ver += 1
pyt
._dt = INFINITY
pyt
._ver += 1
canceled = True
# drain what __fire could have been queued already
while c.len() > 0:
c.recv()
self
._mu.unlock()
pyt
._mu.unlock()
return canceled
# reset rearms the timer.
#
# the timer must be either already stopped or expired.
def reset(PyTimer
self
, double dt):
_Timer_reset_pyexc(
self
, dt)
cdef void _reset(PyTimer
self
, double dt) nogil:
self
._mu.lock()
if
self
._dt != INFINITY:
self
._mu.unlock()
def reset(PyTimer
pyt
, double dt):
_Timer_reset_pyexc(
pyt
, dt)
cdef void _reset(PyTimer
pyt
, double dt) nogil:
pyt
._mu.lock()
if
pyt
._dt != INFINITY:
pyt
._mu.unlock()
panic("Timer.reset: the timer is armed; must be stopped or expired")
self
._dt = dt
self
._ver += 1
pyt
._dt = dt
pyt
._ver += 1
# FIXME uses gil.
# TODO rework timers so that new timer does not spawn new goroutine.
ok = False
with gil:
nogilready = pychan(dtype='C.structZ')
pygo(
self.__fire, self, dt, self
._ver, nogilready)
pygo(
pyt.__fire, pyt, dt, pyt
._ver, nogilready)
nogilready.recv()
ok = True
self
._mu.unlock()
pyt
._mu.unlock()
if not ok:
panic("timer: reset: failed")
cdef void __fire(PyTimer
self
, double dt, int ver, pychan nogilready) except +topyexc:
cdef void __fire(PyTimer
pyt
, double dt, int ver, pychan nogilready) except +topyexc:
with nogil:
nogilready.chan_structZ().close()
self
.___fire(dt, ver)
cdef void ___fire(PyTimer
self
, double dt, int ver) nogil:
c =
self
.c.chan_double()
pyt
.___fire(dt, ver)
cdef void ___fire(PyTimer
pyt
, double dt, int ver) nogil:
c =
pyt
.c.chan_double()
sleep(dt)
self
._mu.lock()
if
self
._ver != ver:
self
._mu.unlock()
pyt
._mu.lock()
if
pyt
._ver != ver:
pyt
._mu.unlock()
return # the timer was stopped/resetted - don't fire it
self
._dt = INFINITY
pyt
._dt = INFINITY
# send under ._mu so that .stop can be sure that if it sees
# ._dt = INFINITY, there is no ongoing .c send.
if
self
._f is None:
if
pyt
._f is None:
c.send(now())
self
._mu.unlock()
pyt
._mu.unlock()
return
self
._mu.unlock()
pyt
._mu.unlock()
# call ._f not from under ._mu not to deadlock e.g. if ._f wants to reset the timer.
with gil:
ok = _callpyf(
self
._f)
ok = _callpyf(
pyt
._f)
if not ok:
panic("timer: fire: failed")
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment