Commit 689dc862 authored by Kirill Smelkov's avatar Kirill Smelkov

libgolang/{gevent,thread}: Restructure to keep functions that access Python localized

In the next patch we will fix runtime functions that work at Python
level to preserve user Python exception state. Before that, as a
preparatory step, restructure runtimes code, so that all such
Python-accessing functions are grouped together.
parent b4feee6f
...@@ -57,8 +57,8 @@ cdef class _togo: ...@@ -57,8 +57,8 @@ cdef class _togo:
cdef void *arg cdef void *arg
# internal functions that work under gil
cdef nogil: cdef nogil:
# XXX better panic with pyexc object and detect that at recover side? # XXX better panic with pyexc object and detect that at recover side?
bint _go(void (*f)(void *), void *arg): bint _go(void (*f)(void *), void *arg):
...@@ -68,55 +68,64 @@ cdef nogil: ...@@ -68,55 +68,64 @@ cdef nogil:
g.start() g.start()
return True return True
void go(void (*f)(void *), void *arg): _libgolang_sema* _sema_alloc():
ok = _go(f, arg)
if not ok:
panic("pyxgo: gevent: go: failed")
_libgolang_sema* sema_alloc():
with gil: with gil:
pygsema = Semaphore() pygsema = Semaphore()
Py_INCREF(pygsema) Py_INCREF(pygsema)
return <_libgolang_sema*>pygsema return <_libgolang_sema*>pygsema
# libgolang checks for NULL return
bint _sema_free(_libgolang_sema *gsema): bint _sema_free(_libgolang_sema *gsema):
with gil: with gil:
pygsema = <PYGSema>gsema pygsema = <PYGSema>gsema
Py_DECREF(pygsema) Py_DECREF(pygsema)
return True return True
void sema_free(_libgolang_sema *gsema):
ok = _sema_free(gsema)
if not ok:
panic("pyxgo: gevent: sema: free: failed")
bint _sema_acquire(_libgolang_sema *gsema): bint _sema_acquire(_libgolang_sema *gsema):
with gil: with gil:
pygsema = <PYGSema>gsema pygsema = <PYGSema>gsema
pygsema.acquire() pygsema.acquire()
return True return True
void sema_acquire(_libgolang_sema *gsema):
ok = _sema_acquire(gsema)
if not ok:
panic("pyxgo: gevent: sema: acquire: failed")
bint _sema_release(_libgolang_sema *gsema): bint _sema_release(_libgolang_sema *gsema):
with gil: with gil:
pygsema = <PYGSema>gsema pygsema = <PYGSema>gsema
pygsema.release() pygsema.release()
return True return True
void sema_release(_libgolang_sema *gsema):
ok = _sema_release(gsema)
if not ok:
panic("pyxgo: gevent: sema: release: failed")
bint _nanosleep(uint64_t dt): bint _nanosleep(uint64_t dt):
cdef double dt_s = dt * 1E-9 cdef double dt_s = dt * 1E-9
with gil: with gil:
pygsleep(dt_s) pygsleep(dt_s)
return True return True
# nogil runtime API
cdef nogil:
void go(void (*f)(void *), void *arg):
ok = _go(f, arg)
if not ok:
panic("pyxgo: gevent: go: failed")
_libgolang_sema* sema_alloc():
sema = _sema_alloc()
return sema # libgolang checks for NULL return
void sema_free(_libgolang_sema *gsema):
ok = _sema_free(gsema)
if not ok:
panic("pyxgo: gevent: sema: free: failed")
void sema_acquire(_libgolang_sema *gsema):
ok = _sema_acquire(gsema)
if not ok:
panic("pyxgo: gevent: sema: acquire: failed")
void sema_release(_libgolang_sema *gsema):
ok = _sema_release(gsema)
if not ok:
panic("pyxgo: gevent: sema: release: failed")
void nanosleep(uint64_t dt): void nanosleep(uint64_t dt):
ok = _nanosleep(dt) ok = _nanosleep(dt)
if not ok: if not ok:
......
...@@ -95,9 +95,22 @@ IF POSIX: ...@@ -95,9 +95,22 @@ IF POSIX:
from posix.time cimport clock_gettime, nanosleep as posix_nanosleep, timespec, CLOCK_REALTIME from posix.time cimport clock_gettime, nanosleep as posix_nanosleep, timespec, CLOCK_REALTIME
from libc.errno cimport errno, EINTR from libc.errno cimport errno, EINTR
ELSE: ELSE:
# for !posix timing fallback # !posix via-gil timing fallback
import time as pytimemod import time as pytimemod
cdef nogil:
bint _nanosleep(double dt_s):
with gil:
pytimemod.sleep(dt_s)
return True
(double, bint) _nanotime():
cdef double t_s
with gil:
t_s = pytimemod.time()
return t_s, True
DEF i1E9 = 1000000000 DEF i1E9 = 1000000000
# 987654321 # 987654321
...@@ -139,13 +152,9 @@ cdef nogil: ...@@ -139,13 +152,9 @@ cdef nogil:
if err == -1: if err == -1:
panic("pyxgo: thread: nanosleep: nanosleep failed") # XXX +errno panic("pyxgo: thread: nanosleep: nanosleep failed") # XXX +errno
ELSE: ELSE:
bint _nanosleep(uint64_t dt):
cdef double dt_s = dt * 1E-9 # no overflow possible
with gil:
pytimemod.sleep(dt_s)
return True
void nanosleep(uint64_t dt): void nanosleep(uint64_t dt):
ok = _nanosleep(dt) cdef double dt_s = dt * 1E-9 # no overflow possible
ok = _nanosleep(dt_s)
if not ok: if not ok:
panic("pyxgo: thread: nanosleep: pytime.sleep failed") panic("pyxgo: thread: nanosleep: pytime.sleep failed")
...@@ -161,19 +170,14 @@ cdef nogil: ...@@ -161,19 +170,14 @@ cdef nogil:
panic("pyxgo: thread: nanotime: clock_gettime -> overflow") panic("pyxgo: thread: nanotime: clock_gettime -> overflow")
return ts.tv_sec*i1E9 + ts.tv_nsec return ts.tv_sec*i1E9 + ts.tv_nsec
ELSE: ELSE:
(uint64_t, bint) _nanotime():
cdef double t_s
with gil:
t_s = pytimemod.time()
t_ns = t_s * 1E9
if t_ns > UINT64_MAX:
panic("pyxgo: thread: nanotime: time overflow")
return <uint64_t>t_ns, True
uint64_t nanotime(): uint64_t nanotime():
t, ok = _nanotime() t_s, ok = _nanotime()
if not ok: if not ok:
panic("pyxgo: thread: nanotime: pytime.time failed") panic("pyxgo: thread: nanotime: pytime.time failed")
return t t_ns = t_s * 1E9
if t_ns > UINT64_MAX:
panic("pyxgo: thread: nanotime: time overflow")
return <uint64_t>t_ns
# XXX const # XXX const
......
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