Commit 28cca409 authored by Jason Madden's avatar Jason Madden

libuv sets ref status on start; timer watchers special case start references....

libuv sets ref status on start; timer watchers special case start references. fixes test__queue and test__order.
parent 437f12c0
......@@ -147,6 +147,7 @@ class watcher(object):
self._watcher_ffi_set_priority(priority)
self._watcher_ffi_init(args)
self._watcher_ffi_set_init_ref(ref)
def _watcher_create(self, ref): # pylint:disable=unused-argument
self._handle = type(self).new_handle(self)
......@@ -157,6 +158,9 @@ class watcher(object):
def _watcher_new(self):
return type(self).new(self._watcher_struct_pointer_type)
def _watcher_ffi_set_init_ref(self, ref):
pass
def _watcher_ffi_set_priority(self, priority):
pass
......@@ -268,9 +272,9 @@ class watcher(object):
raise TypeError('callback must be callable, not None')
self.callback = callback
self.args = args or _NOARGS
self._watcher_ffi_start_unref()
self.loop._keepaliveset.add(self)
self._watcher_ffi_start()
self._watcher_ffi_start_unref()
def stop(self):
self._watcher_ffi_stop_ref()
......
......@@ -68,6 +68,12 @@ class watcher(_base.watcher):
_LIB = libev
_watcher_prefix = 'ev'
# Flags is a bitfield with the following meaning:
# 0000 -> default, referenced (when active)
# 0010 -> ev_unref has been called
# 0100 -> not referenced; independent of 0010
_flags = 0
def __init__(self, _loop, ref=True, priority=None, args=_base._NOARGS):
if ref:
self._flags = 0
......@@ -88,14 +94,15 @@ class watcher(_base.watcher):
self._watcher_start(self.loop._ptr, self._watcher)
def _watcher_ffi_ref(self):
if self._flags & 2:
if self._flags & 2: # we've told libev we're not referenced
self.loop.ref()
self._flags &= ~2
def _watcher_ffi_unref(self):
if self._flags & 6 == 4:
# We're not referenced, but we haven't told libev that
self.loop.unref()
self._flags |= 2
self._flags |= 2 # now we've told libev
def _get_ref(self):
return False if self._flags & 4 else True
......@@ -110,10 +117,12 @@ class watcher(_base.watcher):
else:
if self._flags & 4:
return # ref is already False
self._flags |= 4
self._flags |= 4 # we're not referenced
if not self._flags & 2 and libev.ev_is_active(self._watcher):
# we haven't told libev we're not referenced, but it thinks we're
# active so we need to undo that
self.loop.unref()
self._flags |= 2
self._flags |= 2 # libev knows we're not referenced
ref = property(_get_ref, _set_ref)
......
......@@ -60,6 +60,9 @@ class watcher(_base.watcher):
del self._watcher
def _watcher_ffi_set_init_ref(self, ref):
self.ref = ref
def _watcher_ffi_set_priority(self, priority):
# libuv has no concept of priority
pass
......@@ -302,6 +305,16 @@ class timer(_base.TimerMixin, watcher):
_again = False
def _watcher_ffi_start_unref(self):
# Don't manipulate the ref status different from
# how we were created. Doing so causes test__queue
# to have lots of LoopExit exceptions.
# XXX It's not totally clear why.
pass
def _watcher_ffi_stop_ref(self):
pass
def _watcher_ffi_init(self, args):
self._watcher_init(self.loop._ptr, self._watcher)
self._after, self._repeat = args
......
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