class epoller(object):
exc_handler = None
- def __init__(self):
+ def __init__(self, check=None):
self.registered = {}
+ self.fdcache = {}
self.lock = threading.RLock()
self.ep = None
self.th = None
self.stopped = False
+ self.loopcheck = set()
+ if check is not None:
+ self.loopcheck.add(check)
self._daemon = True
@staticmethod
ep = select.epoll()
try:
with self.lock:
- for fd, (ob, evs) in self.registered.items():
- ep.register(fd, evs)
+ try:
+ for fd, (ob, evs) in self.registered.items():
+ ep.register(fd, evs)
+ except:
+ self.registered.clear()
+ raise
self.ep = ep
while self.registered:
+ for ck in self.loopcheck:
+ ck(self)
if self.stopped:
self._closeall()
break
if fd in self.registered:
nevs = self._evsfor(ch)
if nevs == 0:
+ del self.fdcache[ch]
del self.registered[fd]
ep.unregister(fd)
self._cb(ch, "close")
ch.close()
return
ch.watcher = self
+ self.fdcache[ch] = fd
self.registered[fd] = (ch, evs)
if self.ep:
self.ep.register(fd, evs)
def remove(self, ch, ignore=False):
with self.lock:
- fd = ch.fileno()
- if fd not in self.registered:
+ try:
+ fd = self.fdcache[ch]
+ except KeyError:
if ignore:
return
raise KeyError("fd %i is not registered" % fd)
pch, cevs = self.registered[fd]
if pch is not ch:
raise ValueError("fd %i registered via object %r, cannot remove with %r" % (pch, ch))
+ del self.fdcache[ch]
del self.registered[fd]
if self.ep:
self.ep.unregister(fd)
def update(self, ch, ignore=False):
with self.lock:
- fd = ch.fileno()
- if fd not in self.registered:
+ try:
+ fd = self.fdcache[ch]
+ except KeyError:
if ignore:
return
raise KeyError("fd %i is not registered" % fd)
raise ValueError("fd %i registered via object %r, cannot update with %r" % (pch, ch))
evs = self._evsfor(ch)
if evs == 0:
+ del self.fdcache[ch]
del self.registered[fd]
if self.ep:
self.ep.unregister(fd)
self.wp = -1
def currentwatcher(io, current):
- def run():
- while current:
- current.wait()
- io.stop()
- threading.Thread(target=run, name="Current watcher").start()
+ def check(io):
+ if not current:
+ io.stop()
+ io.loopcheck.add(check)