summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Nichols <tmnichols@gmail.com>2010-06-28 11:06:26 -0400
committerTom Nichols <tmnichols@gmail.com>2010-06-28 11:06:26 -0400
commit15ac3e9fba8fe63b4de64564533d7269def9041e (patch)
tree749a85f5e3b3aa0a32cb42eebee358274c60031a
parente8d37b409c0e29ebb6dcfac2651d5cedc07af965 (diff)
downloadslixmpp-15ac3e9fba8fe63b4de64564533d7269def9041e.tar.gz
slixmpp-15ac3e9fba8fe63b4de64564533d7269def9041e.tar.bz2
slixmpp-15ac3e9fba8fe63b4de64564533d7269def9041e.tar.xz
slixmpp-15ac3e9fba8fe63b4de64564533d7269def9041e.zip
race condition where we were transitioning to 'disconnected' and immediately reconnecting in another thread before the socket.close call occurred. Now we're locking the state machine until the disconnect routine completes.
-rw-r--r--sleekxmpp/xmlstream/xmlstream.py39
1 files changed, 20 insertions, 19 deletions
diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py
index 6dbe7b30..b669a31d 100644
--- a/sleekxmpp/xmlstream/xmlstream.py
+++ b/sleekxmpp/xmlstream/xmlstream.py
@@ -59,7 +59,7 @@ class XMLStream(object):
self.ssl_support = ssl_support
self.escape_quotes = escape_quotes
self.state = statemachine.StateMachine(('disconnected','connecting',
- 'connected'))
+ 'connected'))
self.should_reconnect = True
self.setSocket(socket)
@@ -240,7 +240,7 @@ class XMLStream(object):
if self.should_reconnect:
self.disconnect(reconnect=True)
- logging.debug('Quitting Process thread')
+ logging.debug('Quitting Process thread')
def __readXML(self):
"Parses the incoming stream, adding to xmlin queue as it goes"
@@ -302,23 +302,24 @@ class XMLStream(object):
return True
def disconnect(self, reconnect=False):
- if not self.state.transition('connected','disconnected'):
- logging.warning("Already disconnected.")
- return
- logging.debug("Disconnecting...")
- self.sendRaw(self.stream_footer)
- time.sleep(5)
- #send end of stream
- #wait for end of stream back
- try:
-# self.socket.shutdown(socket.SHUT_RDWR)
- self.socket.close()
- except socket.error as (errno,strerror):
- logging.exception("Error while disconnecting. Socket Error #%s: %s" % (errno, strerror))
- try:
- self.filesocket.close()
- except socket.error as (errno,strerror):
- logging.exception("Error closing filesocket.")
+ with self.state.transition_ctx('connected','disconnected') as locked:
+ if not locked:
+ logging.warning("Already disconnected.")
+ return
+ logging.debug("Disconnecting...")
+ self.sendRaw(self.stream_footer)
+ time.sleep(5)
+ #send end of stream
+ #wait for end of stream back
+ try:
+# self.socket.shutdown(socket.SHUT_RDWR)
+ self.socket.close()
+ except socket.error as (errno,strerror):
+ logging.exception("Error while disconnecting. Socket Error #%s: %s" % (errno, strerror))
+ try:
+ self.filesocket.close()
+ except socket.error as (errno,strerror):
+ logging.exception("Error closing filesocket.")
if reconnect: self.connect()