Commit 55dd7e9e authored by Jason Madden's avatar Jason Madden

enough libuv work that bench_sendall runs. perf is about the same as with libev/cffi on os x.

parent c9bdfd3f
...@@ -57,13 +57,14 @@ class AbstractWatcherType(type): ...@@ -57,13 +57,14 @@ class AbstractWatcherType(type):
@classmethod @classmethod
def _fill_watcher(cls, name, bases, cls_dict): def _fill_watcher(cls, name, bases, cls_dict):
def _mro_get(attr, bases): def _mro_get(attr, bases, error=True):
for b in bases: for b in bases:
try: try:
return getattr(b, attr) return getattr(b, attr)
except AttributeError: except AttributeError:
continue continue
raise AttributeError(attr) if error:
raise AttributeError(attr)
_watcher_prefix = cls_dict.get('_watcher_prefix') or _mro_get('_watcher_prefix', bases) _watcher_prefix = cls_dict.get('_watcher_prefix') or _mro_get('_watcher_prefix', bases)
if '_watcher_type' not in cls_dict: if '_watcher_type' not in cls_dict:
...@@ -80,12 +81,19 @@ class AbstractWatcherType(type): ...@@ -80,12 +81,19 @@ class AbstractWatcherType(type):
LazyOnClass.lazy(cls_dict, _watcher_is_active) LazyOnClass.lazy(cls_dict, _watcher_is_active)
watcher_struct_pattern = (cls_dict.get('_watcher_struct_pattern')
or _mro_get('_watcher_struct_pattern', bases, False)
or 'struct %s')
watcher_struct_name = watcher_struct_pattern % (watcher_type,)
def _watcher_struct_pointer_type(self): def _watcher_struct_pointer_type(self):
return self._FFI.typeof('struct ' + self._watcher_type + '*') return self._FFI.typeof(watcher_struct_name + ' *')
LazyOnClass.lazy(cls_dict, _watcher_struct_pointer_type) LazyOnClass.lazy(cls_dict, _watcher_struct_pointer_type)
callback_name = cls_dict.get('watcher_callback_name', '_gevent_generic_callback') callback_name = (cls_dict.get('_watcher_callback_name')
or _mro_get('_watcher_callback_name', bases, False)
or '_gevent_generic_callback')
def _watcher_callback(self): def _watcher_callback(self):
return self._FFI.addressof(self._LIB, callback_name) return self._FFI.addressof(self._LIB, callback_name)
...@@ -147,6 +155,9 @@ class watcher(object): ...@@ -147,6 +155,9 @@ class watcher(object):
def _watcher_ffi_start(self): def _watcher_ffi_start(self):
raise NotImplementedError() raise NotImplementedError()
def _watcher_ffi_stop(self):
self._watcher_stop(self.loop._ptr, self._watcher)
def _watcher_ffi_ref(self): def _watcher_ffi_ref(self):
raise NotImplementedError() raise NotImplementedError()
...@@ -238,7 +249,7 @@ class watcher(object): ...@@ -238,7 +249,7 @@ class watcher(object):
def stop(self): def stop(self):
self._watcher_ffi_ref() self._watcher_ffi_ref()
self._watcher_stop(self.loop._ptr, self._watcher) self._watcher_ffi_stop()
self.loop._keepaliveset.discard(self) self.loop._keepaliveset.discard(self)
self.callback = None self.callback = None
...@@ -263,18 +274,29 @@ class watcher(object): ...@@ -263,18 +274,29 @@ class watcher(object):
watcher = AbstractWatcherType('watcher', (object,), dict(watcher.__dict__)) watcher = AbstractWatcherType('watcher', (object,), dict(watcher.__dict__))
import functools
def not_while_active(func):
@functools.wraps(func)
def nw(self, *args, **kwargs):
if self.active:
raise AttributeError("not while active")
func(self, *args, **kwargs)
return nw
class IoMixin(object): class IoMixin(object):
EVENT_MASK = 0 EVENT_MASK = 0
def __init__(self, loop, fd, events, ref=True, priority=None): def __init__(self, loop, fd, events, ref=True, priority=None, _args=None):
# XXX: Win32: Need to vfd_open the fd and free the old one? # XXX: Win32: Need to vfd_open the fd and free the old one?
# XXX: Win32: Need a destructor to free the old fd? # XXX: Win32: Need a destructor to free the old fd?
if fd < 0: if fd < 0:
raise ValueError('fd must be non-negative: %r' % fd) raise ValueError('fd must be non-negative: %r' % fd)
if events & ~self.EVENT_MASK: if events & ~self.EVENT_MASK:
raise ValueError('illegal event mask: %r' % events) raise ValueError('illegal event mask: %r' % events)
super(IoMixin, self).__init__(loop, ref=ref, priority=priority, args=(fd, events)) super(IoMixin, self).__init__(loop, ref=ref, priority=priority,
args=_args or (fd, events))
def start(self, callback, *args, **kwargs): def start(self, callback, *args, **kwargs):
args = args or _NOARGS args = args or _NOARGS
......
...@@ -15,7 +15,12 @@ except ImportError: ...@@ -15,7 +15,12 @@ except ImportError:
raise raise
# CFFI/PyPy # CFFI/PyPy
from gevent.libev import corecffi as _core lib = os.environ.get('GEVENT_CORE_CFFI_ONLY')
if lib == 'libuv':
from gevent.libuv import loop as _core
else:
from gevent.libev import corecffi as _core
copy_globals(_core, globals()) copy_globals(_core, globals())
......
...@@ -113,24 +113,24 @@ typedef struct uv_fs_poll_s uv_fs_poll_t; ...@@ -113,24 +113,24 @@ typedef struct uv_fs_poll_s uv_fs_poll_t;
// callbacks with the same signature // callbacks with the same signature
typedef void (*uv_close_cb)(uv_handle_t *handle); typedef void (*uv_close_cb)(void *handle);
typedef void (*uv_idle_cb)(uv_idle_t *handle); typedef void (*uv_idle_cb)(void *handle);
typedef void (*uv_timer_cb)(uv_timer_t *handle); typedef void (*uv_timer_cb)(void *handle);
typedef void (*uv_check_cb)(uv_check_t* handle); typedef void (*uv_check_cb)(void* handle);
typedef void (*uv_async_cb)(uv_async_t* handle); typedef void (*uv_async_cb)(void* handle);
typedef void (*uv_prepare_cb)(uv_prepare_t *handle); typedef void (*uv_prepare_cb)(void*handle);
// callbacks with distinct sigs // callbacks with distinct sigs
typedef void (*uv_walk_cb)(uv_handle_t *handle, void *arg); typedef void (*uv_walk_cb)(void *handle, void *arg);
typedef void (*uv_poll_cb)(uv_poll_t *handle, int status, int events); typedef void (*uv_poll_cb)(void *handle, int status, int events);
typedef void (*uv_signal_cb)(uv_signal_t *handle, int signum); typedef void (*uv_signal_cb)(void *handle, int signum);
// Callback passed to uv_fs_event_start() which will be called // Callback passed to uv_fs_event_start() which will be called
// repeatedly after the handle is started. If the handle was started // repeatedly after the handle is started. If the handle was started
// with a directory the filename parameter will be a relative path to // with a directory the filename parameter will be a relative path to
// a file contained in the directory. The events parameter is an ORed // a file contained in the directory. The events parameter is an ORed
// mask of uv_fs_event elements. // mask of uv_fs_event elements.
typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename, int events, int status); typedef void (*uv_fs_event_cb)(void* handle, const char* filename, int events, int status);
typedef struct { typedef struct {
long tv_sec; long tv_sec;
...@@ -288,10 +288,10 @@ static void (*gevent_noop)(void* handle); ...@@ -288,10 +288,10 @@ static void (*gevent_noop)(void* handle);
* watcher types has a 'void* data' that stores the CFFI handle to the Python watcher * watcher types has a 'void* data' that stores the CFFI handle to the Python watcher
* object. * object.
*/ */
static void _gevent_generic_callback0(uv_handle_t* handle); // no extra args static void _gevent_generic_callback0(void* handle); // no extra args
static void _gevent_generic_callback1(uv_handle_t* handle, int arg); // one extra args. Everything will funnel through this static void _gevent_generic_callback1(void* handle, int arg); // one extra args. Everything will funnel through this
static void _gevent_poll_callback2(uv_handle_t* handle, int status, int events); static void _gevent_poll_callback2(void* handle, int status, int events);
static void _gevent_fs_event_callback3(uv_handle_t* handle, const char* filename, int events, int status); static void _gevent_fs_event_callback3(void* handle, const char* filename, int events, int status);
typedef struct _gevent_fs_poll_s { typedef struct _gevent_fs_poll_s {
uv_fs_poll_t handle; uv_fs_poll_t handle;
......
...@@ -8,8 +8,9 @@ static void _gevent_noop(void*handle) {} ...@@ -8,8 +8,9 @@ static void _gevent_noop(void*handle) {}
static void (*gevent_noop)(void* handle) = &_gevent_noop; static void (*gevent_noop)(void* handle) = &_gevent_noop;
static void _gevent_generic_callback1(uv_handle_t* watcher, int arg) static void _gevent_generic_callback1(void* vwatcher, int arg)
{ {
uv_handle_t* watcher = (uv_handle_t*)vwatcher;
void* handle = watcher->data; void* handle = watcher->data;
int cb_result = python_callback(handle, arg); int cb_result = python_callback(handle, arg);
switch(cb_result) { switch(cb_result) {
...@@ -34,17 +35,17 @@ static void _gevent_generic_callback1(uv_handle_t* watcher, int arg) ...@@ -34,17 +35,17 @@ static void _gevent_generic_callback1(uv_handle_t* watcher, int arg)
} }
static void _gevent_generic_callback0(uv_handle_t* handle) static void _gevent_generic_callback0(void* handle)
{ {
_gevent_generic_callback1(handle, 0); _gevent_generic_callback1(handle, 0);
} }
static void _gevent_poll_callback2(uv_handle_t* handle, int status, int events) static void _gevent_poll_callback2(void* handle, int status, int events)
{ {
_gevent_generic_callback1(handle, status < 0 ? status : events); _gevent_generic_callback1(handle, status < 0 ? status : events);
} }
static void _gevent_fs_event_callback3(uv_handle_t* handle, const char* filename, int events, int status) static void _gevent_fs_event_callback3(void* handle, const char* filename, int events, int status)
{ {
_gevent_generic_callback1(handle, status < 0 ? status : events); _gevent_generic_callback1(handle, status < 0 ? status : events);
} }
......
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