Yann Leboulanger pushed to branch master at gajim / python-nbxmpp
Commits: e230629a by Jeff 'Raid' Baitis at 2018-01-02T22:14:34-08:00 Detect invalid file handles when passed to SelectIdleQueue
- - - - - a80515dc by Yann Leboulanger at 2018-01-04T13:50:27+01:00 Merge branch 'master' into 'master'
Detect invalid file handles when passed to SelectIdleQueue
See merge request gajim/python-nbxmpp!12 - - - - -
1 changed file:
- nbxmpp/idlequeue.py
Changes:
===================================== nbxmpp/idlequeue.py ===================================== --- a/nbxmpp/idlequeue.py +++ b/nbxmpp/idlequeue.py @@ -21,6 +21,7 @@ objects and be informed about possible IO from __future__ import unicode_literals
import os +import errno import sys import select import logging @@ -59,7 +60,6 @@ PENDING_READ = 3 # waiting read event PENDING_WRITE = 4 # waiting write event IS_CLOSED = 16 # channel closed
- def get_idlequeue(): """ Get an appropriate idlequeue @@ -353,7 +353,7 @@ class IdleQueue(object):
:param obj: the IdleObject :param writable: True if obj has data to sent - :param readable: True if obj expects data to be reiceived + :param readable: True if obj expects data to be received """ if obj.fd == -1: return @@ -438,16 +438,15 @@ class IdleQueue(object): return True try: waiting_descriptors = self.selector.poll(0) - except select.error as e: + except OSError as e: waiting_descriptors = [] - if e[0] != 4: # interrupt + if e.errno != errno.EINTR: raise for fd, flags in waiting_descriptors: self._process_events(fd, flags) self._check_time_events() return True
- class SelectIdleQueue(IdleQueue): """ Extends IdleQueue to use select.select() for polling @@ -456,6 +455,31 @@ class SelectIdleQueue(IdleQueue): support io_add_watch properly (yet) """
+ def checkQueue(self): + """ + Iterates through all known file descriptors and uses os.stat to check if they're valid. + Greatly improves performance if the caller hands us and expects notification on an invalid file handle. + """ + bad_fds=[] + union={} + union.update(self.write_fds) + union.update(self.read_fds) + union.update(self.error_fds) + for fd in (union.keys()): + try: + status = os.stat(fd) + except OSError as e: + # This file descriptor is invalid. Add to list for closure. + bad_fds.append(fd) + + for fd in (bad_fds): + obj = self.queue.get(fd) + if obj is None: + self.unplug_idle(fd) + return + self.remove_timeout(fd) + self.unplug_idle(fd) + def _init_idle(self): """ Create a dict, which maps file/pipe/sock descriptor to glib event id @@ -466,7 +490,7 @@ class SelectIdleQueue(IdleQueue):
def _add_idle(self, fd, flags): """ - This method is called when we plug a new idle object. Remove descriptor + This method is called when we plug a new idle object. Add descriptor to read/write/error lists, according flags """ if flags & 3: @@ -494,9 +518,10 @@ class SelectIdleQueue(IdleQueue): try: waiting_descriptors = select.select(list(self.read_fds.keys()), list(self.write_fds.keys()), list(self.error_fds.keys()), 0) - except select.error as e: + except OSError as e: waiting_descriptors = ((), (), ()) - if e[0] != 4: # interrupt + if e.errno != errno.EINTR: + self.checkQueue() raise for fd in waiting_descriptors[0]: q = self.queue.get(fd)
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/compare/ae4435eae456d0e89341b9e391...
--- View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/compare/ae4435eae456d0e89341b9e391... You're receiving this email because of your account on dev.gajim.org.