diff options
author | Jacek Konieczny <jajcus@jajcus.net> | 2009-04-24 10:43:59 +0400 |
---|---|---|
committer | Jacek Konieczny <jajcus@jajcus.net> | 2009-04-24 10:43:59 +0400 |
commit | 5f287e8079ad95d249dae35f0ea96e820f5a4ced (patch) | |
tree | ba82d120ceb47b068437456e23da9fe99f91b742 /pyxmpp | |
parent | 70caf3ed4b1e76ccfc3d3f9152a51e08a2f3f201 (diff) |
- ExpiringDictionary + StanzaProcessor timeout threadsafety patch by chris/digsby.com
Diffstat (limited to 'pyxmpp')
-rw-r--r-- | pyxmpp/expdict.py | 21 | ||||
-rw-r--r-- | pyxmpp/stanzaprocessor.py | 22 |
2 files changed, 31 insertions, 12 deletions
diff --git a/pyxmpp/expdict.py b/pyxmpp/expdict.py index defe21b..0d01281 100644 --- a/pyxmpp/expdict.py +++ b/pyxmpp/expdict.py @@ -23,6 +23,10 @@ __docformat__="restructuredtext en" import time import threading +__all__ = ['ExpiringDictionary'] + +sentinel = object() + class ExpiringDictionary(dict): """An extension to standard Python dictionary objects which implements item expiration. @@ -70,6 +74,18 @@ class ExpiringDictionary(dict): finally: self._lock.release() + def pop(self,key,default=sentinel): + self._lock.acquire() + try: + self._expire_item(key) + del self._timeouts[key] + if default is not sentinel: + return dict.pop(self,key,default) + else: + return dict.pop(self,key) + finally: + self._lock.release() + def __setitem__(self,key,value): return self.set_item(key,value) @@ -119,14 +135,15 @@ class ExpiringDictionary(dict): - `key`: any hashable value""" (timeout,callback)=self._timeouts[key] if timeout<=time.time(): + item = dict.pop(self, key) + del self._timeouts[key] if callback: try: - callback(key,dict.__getitem__(self,key)) + callback(key,item) except TypeError: try: callback(key) except TypeError: callback() - del self[key] # vi: sts=4 et sw=4 diff --git a/pyxmpp/stanzaprocessor.py b/pyxmpp/stanzaprocessor.py index 7349b95..be9c5b4 100644 --- a/pyxmpp/stanzaprocessor.py +++ b/pyxmpp/stanzaprocessor.py @@ -107,19 +107,21 @@ class StanzaProcessor: ufr=fr.as_unicode() else: ufr=None - if self._iq_response_handlers.has_key((sid,ufr)): - key=(sid,ufr) - elif ( (fr == self.peer or fr == self.me or fr == self.me.bare()) - and self._iq_response_handlers.has_key((sid,None))): - key=(sid,None) - else: - return False - res_handler, err_handler = self._iq_response_handlers[key] - if stanza.get_type()=="result": + res_handler = err_handler = None + try: + res_handler, err_handler = self._iq_response_handlers.pop((sid,ufr)) + except KeyError: + if ( (fr==self.peer or fr==self.me or fr==self.me.bare()) ): + try: + res_handler, err_handler = self._iq_response_handlers.pop((sid,None)) + except KeyError: + pass + if None is res_handler is err_handler: + return False + if typ=="result": response = res_handler(stanza) else: response = err_handler(stanza) - del self._iq_response_handlers[key] self.process_response(response) return True |