Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gevent
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gevent
Commits
7a24cc11
Commit
7a24cc11
authored
Jan 23, 2018
by
Jason Madden
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Go back to caching the watcher pointer.
parent
38451247
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
67 additions
and
77 deletions
+67
-77
src/gevent/libev/corecext.ppyx
src/gevent/libev/corecext.ppyx
+67
-60
src/gevent/python.pxd
src/gevent/python.pxd
+0
-17
No files found.
src/gevent/libev/corecext.ppyx
View file @
7a24cc11
...
...
@@ -22,9 +22,15 @@
cimport cython
cimport libev
# Note this is not the standard cython 'cpython' (which has a backwards compat alias of 'python')
# it's our custom def. If it's not on the include path, we get warned.
from python cimport *
from cpython.ref cimport Py_INCREF
from cpython.ref cimport Py_DECREF
from cpython.mem cimport PyMem_Malloc
from cpython.mem cimport PyMem_Free
cdef extern from "Python.h":
int Py_ReprEnter(object)
void Py_ReprLeave(object)
# Work around lack of absolute_import in Cython
# Note for PY3: not doing so will leave reference to locals() on import
...
...
@@ -597,7 +603,7 @@ cdef public class callback [object PyGeventCallbackObject, type PyGeventCallback
return self.callback is not None
def __repr__(self):
if Py_ReprEnter(
<PyObjectPtr>
self) != 0:
if Py_ReprEnter(self) != 0:
return "<...>"
try:
format = self._format()
...
...
@@ -612,7 +618,7 @@ cdef public class callback [object PyGeventCallbackObject, type PyGeventCallback
result += " stopped"
return result + ">"
finally:
Py_ReprLeave(
<PyObjectPtr>
self)
Py_ReprLeave(self)
def _format(self):
return ''
...
...
@@ -634,12 +640,12 @@ DEF FLAG_WATCHER_MASK_UNREF_NEEDS_REF = 0x6
cdef void _python_incref(watcher self):
if not self._flags & FLAG_WATCHER_OWNS_PYREF:
Py_INCREF(
<PyObjectPtr>
self)
Py_INCREF(self)
self._flags |= FLAG_WATCHER_OWNS_PYREF
cdef void _python_decref(watcher self):
if self._flags & FLAG_WATCHER_OWNS_PYREF:
Py_DECREF(
<PyObjectPtr>
self)
Py_DECREF(self)
self._flags &= ~FLAG_WATCHER_OWNS_PYREF
cdef void _libev_ref(watcher self):
...
...
@@ -676,28 +682,41 @@ cdef public class watcher [object PyGeventWatcherObject, type PyGeventWatcher_Ty
cdef public loop loop
cdef object _callback
cdef public tuple args
# By keeping a __watcher cached, the size of the io and timer
# structs becomes 152 bytes and child is 160 and stat is 512 (when
# the start_and_stop is inlined). On 64-bit macOS CPython 2.7. I
# hoped that using libev's data pointer and allocating the
# watchers directly and not as inline members would result in
# overall savings thanks to better padding, but it didn't. And it
# added lots of casts, making the code ugly.
# Table:
# gevent ver | 1.2 | This | +data
# Watcher Kind | | |
# Timer | 120 | 152 | 160
# IO | 120 | 152 | 160
# Child | 128 | 160 | 168
# Stat | 480 | 512 | 512
cdef libev.ev_watcher* __watcher
# By inlining the start_and_stop struct, instead of taking the address
# of a static struct or using the watcher's data pointer, we
# use an additional pointer of memory and incur an additional pointer copy
# on creation.
# But we use fewer pointer accesses for start/stop, and they have
# better cache locality. (Then again, we're bigger)
cdef start_and_stop __ss
cdef libev.ev_any_watcher _any_watcher
# better cache locality. (Then again, we're bigger).
# Right now we're going for size, so we use the pointer. IO/Timer objects
# are then 144 bytes.
cdef start_and_stop* __ss
def __init__(self, loop loop, ref=True, priority=None):
cdef libev.ev_watcher* w = self.__watcher()
if not w or not self.__ss.start or not self.__ss.stop:
if not self.__watcher or not self.__ss.start or not self.__ss.stop:
raise ValueError("Cannot construct a bare watcher")
self.loop = loop
self._flags = 0 if ref else FLAG_WATCHER_UNREF_BEFORE_START
if priority is not None:
libev.ev_set_priority(w, priority)
cdef libev.ev_watcher* __watcher(self):
# We define this as a function to save one pointer of storage
# in our struct.
return NULL
libev.ev_set_priority(self.__watcher, priority)
@property
def ref(self):
...
...
@@ -720,7 +739,7 @@ cdef public class watcher [object PyGeventWatcherObject, type PyGeventWatcher_Ty
if not self.ref:
return # ref is already False
self._flags |= FLAG_WATCHER_UNREF_BEFORE_START
if not self._flags & FLAG_WATCHER_NEEDS_EVREF and libev.ev_is_active(self.__watcher
()
):
if not self._flags & FLAG_WATCHER_NEEDS_EVREF and libev.ev_is_active(self.__watcher):
libev.ev_unref(self.loop._ptr)
self._flags |= FLAG_WATCHER_NEEDS_EVREF
...
...
@@ -736,22 +755,22 @@ cdef public class watcher [object PyGeventWatcherObject, type PyGeventWatcher_Ty
@property
def priority(self):
return libev.ev_priority(self.__watcher
()
)
return libev.ev_priority(self.__watcher)
@priority.setter
def priority(self, int priority):
cdef libev.ev_watcher* w = self.__watcher
()
cdef libev.ev_watcher* w = self.__watcher
if libev.ev_is_active(w):
raise AttributeError("Cannot set priority of an active watcher")
libev.ev_set_priority(w, priority)
@property
def active(self):
return True if libev.ev_is_active(self.__watcher
()
) else False
return True if libev.ev_is_active(self.__watcher) else False
@property
def pending(self):
return True if libev.ev_is_pending(self.__watcher
()
) else False
return True if libev.ev_is_pending(self.__watcher) else False
def start(self, object callback, *args):
self._watcher_start(callback, args)
...
...
@@ -767,7 +786,7 @@ cdef public class watcher [object PyGeventWatcherObject, type PyGeventWatcher_Ty
self.args = args
_libev_unref(self)
_python_incref(self)
self.__ss.start(self.loop._ptr, self.__watcher
()
)
self.__ss.start(self.loop._ptr, self.__watcher)
return 1
cpdef stop(self):
...
...
@@ -777,7 +796,7 @@ cdef public class watcher [object PyGeventWatcherObject, type PyGeventWatcher_Ty
# so this is safe.
self._callback = None
self.args = None
self.__ss.stop(self.loop._ptr, self.__watcher
()
)
self.__ss.stop(self.loop._ptr, self.__watcher)
_python_decref(self)
def feed(self, int revents, object callback, *args):
...
...
@@ -785,11 +804,11 @@ cdef public class watcher [object PyGeventWatcherObject, type PyGeventWatcher_Ty
self.callback = callback
self.args = args
_libev_unref(self)
libev.ev_feed_event(self.loop._ptr, self.__watcher
()
, revents)
libev.ev_feed_event(self.loop._ptr, self.__watcher, revents)
_python_incref(self)
def __repr__(self):
if Py_ReprEnter(
<PyObjectPtr>
self) != 0:
if Py_ReprEnter(self) != 0:
return "<...>"
try:
format = self._format()
...
...
@@ -804,7 +823,7 @@ cdef public class watcher [object PyGeventWatcherObject, type PyGeventWatcher_Ty
result += " args=%r" % (self.args, )
return result + ">"
finally:
Py_ReprLeave(
<PyObjectPtr>
self)
Py_ReprLeave(self)
def _format(self):
return ''
...
...
@@ -841,14 +860,12 @@ cdef public class io(watcher) [object PyGeventIOObject, type PyGeventIO_Type]:
# All the vfd_functions are no-ops on POSIX
cdef int vfd = libev.vfd_open(fd)
libev.ev_io_init(&self._watcher, <void *>gevent_callback_io, vfd, events)
self.__ss = io_ss
self.__watcher = <libev.ev_watcher*>&self._watcher
self.__ss = &io_ss
def __dealloc__(self):
libev.vfd_free(self._watcher.fd)
cdef libev.ev_watcher* __watcher(self):
return <libev.ev_watcher*>&self._watcher
@property
def fd(self):
return libev.vfd_get(self._watcher.fd)
...
...
@@ -897,7 +914,8 @@ cdef public class timer(watcher) [object PyGeventTimerObject, type PyGeventTimer
if repeat < 0.0:
raise ValueError("repeat must be positive or zero: %r" % repeat)
libev.ev_timer_init(&self._watcher, <void *>gevent_callback_timer, after, repeat)
self.__ss = timer_ss
self.__watcher = <libev.ev_watcher*>&self._watcher
self.__ss = &timer_ss
def __init__(self, loop loop, double after=0.0, double repeat=0.0, ref=True, priority=None):
watcher.__init__(self, loop, ref, priority)
...
...
@@ -918,8 +936,6 @@ cdef public class timer(watcher) [object PyGeventTimerObject, type PyGeventTimer
libev.ev_timer_again(self.loop._ptr, &self._watcher)
_python_incref(self)
cdef libev.ev_watcher* __watcher(self):
return <libev.ev_watcher*>&self._watcher
cdef start_and_stop signal_ss = make_ss(<void*>libev.ev_signal_start, <void*>libev.ev_signal_stop)
...
...
@@ -937,13 +953,12 @@ cdef public class signal(watcher) [object PyGeventSignalObject, type PyGeventSig
# 2) "libev: a signal must not be attached to two different loops"
# we probably could check that in LIBEV_EMBED mode, but not in general
libev.ev_signal_init(&self._watcher, <void *>gevent_callback_signal, signalnum)
self.__ss = signal_ss
self.__watcher = <libev.ev_watcher*>&self._watcher
self.__ss = &signal_ss
def __init__(self, loop loop, int signalnum, ref=True, priority=None):
watcher.__init__(self, loop, ref, priority)
cdef libev.ev_watcher* __watcher(self):
return <libev.ev_watcher*>&self._watcher
cdef start_and_stop idle_ss = make_ss(<void*>libev.ev_idle_start, <void*>libev.ev_idle_stop)
...
...
@@ -954,10 +969,9 @@ cdef public class idle(watcher) [object PyGeventIdleObject, type PyGeventIdle_Ty
def __cinit__(self, loop loop, ref=True, priority=None):
libev.ev_idle_init(&self._watcher, <void*>gevent_callback_idle)
self.__ss = idle_ss
self.__watcher = <libev.ev_watcher*>&self._watcher
self.__ss = &idle_ss
cdef libev.ev_watcher* __watcher(self):
return <libev.ev_watcher*>&self._watcher
cdef start_and_stop prepare_ss = make_ss(<void*>libev.ev_prepare_start, <void*>libev.ev_prepare_stop)
...
...
@@ -968,10 +982,9 @@ cdef public class prepare(watcher) [object PyGeventPrepareObject, type PyGeventP
def __cinit__(self, loop loop, ref=True, priority=None):
libev.ev_prepare_init(&self._watcher, <void*>gevent_callback_prepare)
self.__ss = prepare_ss
self.__watcher = <libev.ev_watcher*>&self._watcher
self.__ss = &prepare_ss
cdef libev.ev_watcher* __watcher(self):
return <libev.ev_watcher*>&self._watcher
cdef start_and_stop check_ss = make_ss(<void*>libev.ev_check_start, <void*>libev.ev_check_stop)
...
...
@@ -982,10 +995,9 @@ cdef public class check(watcher) [object PyGeventCheckObject, type PyGeventCheck
def __cinit__(self, loop loop, ref=True, priority=None):
libev.ev_check_init(&self._watcher, <void*>gevent_callback_check)
self.__ss = check_ss
self.__watcher = <libev.ev_watcher*>&self._watcher
self.__ss = &check_ss
cdef libev.ev_watcher* __watcher(self):
return <libev.ev_watcher*>&self._watcher
cdef start_and_stop fork_ss = make_ss(<void*>libev.ev_fork_start, <void*>libev.ev_fork_stop)
...
...
@@ -996,10 +1008,8 @@ cdef public class fork(watcher) [object PyGeventForkObject, type PyGeventFork_Ty
def __cinit__(self, loop loop, ref=True, priority=None):
libev.ev_fork_init(&self._watcher, <void*>gevent_callback_fork)
self.__ss = fork_ss
cdef libev.ev_watcher* __watcher(self):
return <libev.ev_watcher*>&self._watcher
self.__watcher = <libev.ev_watcher*>&self._watcher
self.__ss = &fork_ss
cdef start_and_stop async_ss = make_ss(<void*>libev.ev_async_start, <void*>libev.ev_async_stop)
...
...
@@ -1015,10 +1025,9 @@ cdef public class async_(watcher) [object PyGeventAsyncObject, type PyGeventAsyn
def __cinit__(self, loop loop, ref=True, priority=None):
libev.ev_async_init(&self._watcher, <void*>gevent_callback_async)
self.__ss = async_ss
self.__watcher = <libev.ev_watcher*>&self._watcher
self.__ss = &async_ss
cdef libev.ev_watcher* __watcher(self):
return <libev.ev_watcher*>&self._watcher
def send(self):
_check_loop(self.loop)
...
...
@@ -1039,13 +1048,12 @@ cdef public class child(watcher) [object PyGeventChildObject, type PyGeventChild
raise TypeError('child watchers are only available on the default loop')
libev.gevent_install_sigchld_handler()
libev.ev_child_init(&self._watcher, <void *>gevent_callback_child, pid, trace)
self.__ss = child_ss
self.__watcher = <libev.ev_watcher*>&self._watcher
self.__ss = &child_ss
def __init__(self, loop loop, int pid, bint trace=0, ref=True):
watcher.__init__(self, loop, ref, None)
cdef libev.ev_watcher* __watcher(self):
return <libev.ev_watcher*>&self._watcher
def _format(self):
return ' pid=%r rstatus=%r' % (self.pid, self.rstatus)
...
...
@@ -1091,13 +1099,12 @@ cdef public class stat(watcher) [object PyGeventStatObject, type PyGeventStat_Ty
paths = <bytes>path
self._paths = paths
libev.ev_stat_init(&self._watcher, <void *>gevent_callback_stat, <char*>paths, interval)
self.__ss = stat_ss
self.__watcher = <libev.ev_watcher*>&self._watcher
self.__ss = &stat_ss
def __init__(self, loop loop, str path, float interval=0.0, ref=True, priority=None):
watcher.__init__(self, loop, ref, priority)
cdef libev.ev_watcher* __watcher(self):
return <libev.ev_watcher*>&self._watcher
@property
def attr(self):
...
...
src/gevent/python.pxd
deleted
100644 → 0
View file @
38451247
cdef
extern
from
"Python.h"
:
struct
PyObject
:
pass
ctypedef
PyObject
*
PyObjectPtr
"PyObject*"
void
Py_INCREF
(
PyObjectPtr
)
void
Py_DECREF
(
PyObjectPtr
)
void
Py_XDECREF
(
PyObjectPtr
)
int
Py_ReprEnter
(
PyObjectPtr
)
void
Py_ReprLeave
(
PyObjectPtr
)
int
PyCallable_Check
(
PyObjectPtr
)
cdef
extern
from
"frameobject.h"
:
ctypedef
struct
PyThreadState
:
PyObjectPtr
exc_type
PyObjectPtr
exc_value
PyObjectPtr
exc_traceback
PyThreadState
*
PyThreadState_GET
()
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