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):
@classmethod
def _fill_watcher(cls, name, bases, cls_dict):
def _mro_get(attr, bases):
def _mro_get(attr, bases, error=True):
for b in bases:
try:
return getattr(b, attr)
except AttributeError:
continue
raise AttributeError(attr)
if error:
raise AttributeError(attr)
_watcher_prefix = cls_dict.get('_watcher_prefix') or _mro_get('_watcher_prefix', bases)
if '_watcher_type' not in cls_dict:
......@@ -80,12 +81,19 @@ class AbstractWatcherType(type):
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):
return self._FFI.typeof('struct ' + self._watcher_type + '*')
return self._FFI.typeof(watcher_struct_name + ' *')
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):
return self._FFI.addressof(self._LIB, callback_name)
......@@ -147,6 +155,9 @@ class watcher(object):
def _watcher_ffi_start(self):
raise NotImplementedError()
def _watcher_ffi_stop(self):
self._watcher_stop(self.loop._ptr, self._watcher)
def _watcher_ffi_ref(self):
raise NotImplementedError()
......@@ -238,7 +249,7 @@ class watcher(object):
def stop(self):
self._watcher_ffi_ref()
self._watcher_stop(self.loop._ptr, self._watcher)
self._watcher_ffi_stop()
self.loop._keepaliveset.discard(self)
self.callback = None
......@@ -263,18 +274,29 @@ class watcher(object):
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):
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 a destructor to free the old fd?
if fd < 0:
raise ValueError('fd must be non-negative: %r' % fd)
if events & ~self.EVENT_MASK:
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):
args = args or _NOARGS
......
......@@ -15,7 +15,12 @@ except ImportError:
raise
# 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())
......
......@@ -113,24 +113,24 @@ typedef struct uv_fs_poll_s uv_fs_poll_t;
// callbacks with the same signature
typedef void (*uv_close_cb)(uv_handle_t *handle);
typedef void (*uv_idle_cb)(uv_idle_t *handle);
typedef void (*uv_timer_cb)(uv_timer_t *handle);
typedef void (*uv_check_cb)(uv_check_t* handle);
typedef void (*uv_async_cb)(uv_async_t* handle);
typedef void (*uv_prepare_cb)(uv_prepare_t *handle);
typedef void (*uv_close_cb)(void *handle);
typedef void (*uv_idle_cb)(void *handle);
typedef void (*uv_timer_cb)(void *handle);
typedef void (*uv_check_cb)(void* handle);
typedef void (*uv_async_cb)(void* handle);
typedef void (*uv_prepare_cb)(void*handle);
// callbacks with distinct sigs
typedef void (*uv_walk_cb)(uv_handle_t *handle, void *arg);
typedef void (*uv_poll_cb)(uv_poll_t *handle, int status, int events);
typedef void (*uv_signal_cb)(uv_signal_t *handle, int signum);
typedef void (*uv_walk_cb)(void *handle, void *arg);
typedef void (*uv_poll_cb)(void *handle, int status, int events);
typedef void (*uv_signal_cb)(void *handle, int signum);
// Callback passed to uv_fs_event_start() which will be called
// repeatedly after the handle is started. If the handle was started
// with a directory the filename parameter will be a relative path to
// a file contained in the directory. The events parameter is an ORed
// 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 {
long tv_sec;
......@@ -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
* object.
*/
static void _gevent_generic_callback0(uv_handle_t* 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_poll_callback2(uv_handle_t* 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_generic_callback0(void* handle); // no extra args
static void _gevent_generic_callback1(void* handle, int arg); // one extra args. Everything will funnel through this
static void _gevent_poll_callback2(void* handle, int status, int events);
static void _gevent_fs_event_callback3(void* handle, const char* filename, int events, int status);
typedef struct _gevent_fs_poll_s {
uv_fs_poll_t handle;
......
......@@ -8,8 +8,9 @@ static void _gevent_noop(void*handle) {}
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;
int cb_result = python_callback(handle, arg);
switch(cb_result) {
......@@ -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);
}
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);
}
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);
}
......
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