Author: steve-e Date: 2009-01-03 17:34:58 +0100 (Sat, 03 Jan 2009) New Revision: 10933
Modified: trunk/src/common/xmpp/client_nb.py trunk/src/common/xmpp/idlequeue.py trunk/src/common/xmpp/transports_nb.py trunk/src/gajim.py Log: Revert r10931. Fixes #4632. See #2634
Modified: trunk/src/common/xmpp/client_nb.py =================================================================== --- trunk/src/common/xmpp/client_nb.py 2008-12-31 14:04:42 UTC (rev 10932) +++ trunk/src/common/xmpp/client_nb.py 2009-01-03 16:34:58 UTC (rev 10933) @@ -287,8 +287,7 @@ if self.__dict__.has_key('Dispatcher'): self.Dispatcher.PlugOut() self.got_features = False - # Plugging will send our stream header - dispatcher_nb.Dispatcher().PlugIn(self) + d = dispatcher_nb.Dispatcher().PlugIn(self) on_next_receive('RECEIVE_DOCUMENT_ATTRIBUTES')
elif mode == 'FAILURE': @@ -299,14 +298,16 @@ self.Dispatcher.ProcessNonBlocking(data) if not hasattr(self, 'Dispatcher') or \ self.Dispatcher.Stream._document_attrs is None: - # only partial data received so far - return + self._xmpp_connect_machine( + mode='FAILURE', + data='Error on stream open') if self.incoming_stream_version() == '1.0': if not self.got_features: on_next_receive('RECEIVE_STREAM_FEATURES') else: log.info('got STREAM FEATURES in first recv') self._xmpp_connect_machine(mode='STREAM_STARTED') + else: log.info('incoming stream version less than 1.0') self._xmpp_connect_machine(mode='STREAM_STARTED') @@ -314,11 +315,14 @@ elif mode == 'RECEIVE_STREAM_FEATURES': if data: # sometimes <features> are received together with document - # attributes and sometimes on next receive... sometimes in - # several chunks... + # attributes and sometimes on next receive... self.Dispatcher.ProcessNonBlocking(data) - if self.got_features: - log.info('got STREAM FEATURES after several recv') + if not self.got_features: + self._xmpp_connect_machine( + mode='FAILURE', + data='Missing <features> in 1.0 stream') + else: + log.info('got STREAM FEATURES in second recv') self._xmpp_connect_machine(mode='STREAM_STARTED')
elif mode == 'STREAM_STARTED':
Modified: trunk/src/common/xmpp/idlequeue.py =================================================================== --- trunk/src/common/xmpp/idlequeue.py 2008-12-31 14:04:42 UTC (rev 10932) +++ trunk/src/common/xmpp/idlequeue.py 2009-01-03 16:34:58 UTC (rev 10933) @@ -19,6 +19,7 @@
import select import logging +import gobject log = logging.getLogger('gajim.c.x.idlequeue')
FLAG_WRITE = 20 # write only @@ -114,7 +115,7 @@
def remove_timeout(self, fd): ''' Removes the read timeout ''' - log.debug('read timeout removed for fd %s' % fd) + log.info('read timeout removed for fd %s' % fd) if fd in self.read_timeouts: del(self.read_timeouts[fd])
@@ -125,7 +126,7 @@
A filedescriptor fd can have only one timeout. ''' - log.debug('read timeout set for fd %s on %s seconds' % (fd, seconds)) + log.info('read timeout set for fd %s on %s seconds' % (fd, seconds)) timeout = self.current_time() + seconds self.read_timeouts[fd] = timeout
@@ -134,14 +135,14 @@ Execute and remove alarm callbacks and execute read_timeout() for plugged objects if specified time has ellapsed. ''' - log.debug('check time evs') + log.info('check time evs') current_time = self.current_time()
for fd, timeout in self.read_timeouts.items(): if timeout > current_time: continue if fd in self.queue: - log.info('Calling read_timeout for fd %s' % fd) + log.debug('Calling read_timeout for fd %s' % fd) self.queue[fd].read_timeout() else: self.remove_timeout(fd) @@ -166,7 +167,6 @@ ''' if obj.fd == -1: return - log.info('Plug object fd %s as w:%s r:%s' % (obj.fd, writable, readable)) if obj.fd in self.queue: self.unplug_idle(obj.fd) self.queue[obj.fd] = obj @@ -208,6 +208,7 @@ return False
if flags & PENDING_READ: + #print 'waiting read on %d, flags are %d' % (fd, flags) obj.pollin() return True
@@ -240,14 +241,6 @@ waiting_descriptors = [] if e[0] != 4: # interrupt raise - # Maybe there is still data in ssl buffer: - # Add all sslWrappers where we have pending data. poll doesn't work here - # as it can only check sockets but the data may already be read into - # a ssl internal buffer - descriptors = (fd for fd, flag in waiting_descriptors) - waiting_descriptors.extend((fd, FLAG_READ) for (fd, obj) in - self.queue.iteritems() if not fd in descriptors and - hasattr(obj, '_sslObj') and obj._sslObj.pending()) for fd, flags in waiting_descriptors: self._process_events(fd, flags) self._check_time_events() @@ -297,16 +290,6 @@ try: waiting_descriptors = select.select(self.read_fds.keys(), self.write_fds.keys(), self.error_fds.keys(), 0) - - # Maybe there is still data in ssl buffer: - # Add all sslWrappers where we have pending data. select doesn't work - # here as it can only check sockets but the data may already be read - # into a ssl internal buffer - waiting_descriptors[0].extend(fd for (fd, obj) - in self.queue.iteritems() if not fd in waiting_descriptors[0] and - hasattr(obj, '_sslObj') and obj._sslObj.pending()) - waiting_descriptors = (waiting_descriptors[0], waiting_descriptors[1], - waiting_descriptors[2]) except select.error, e: waiting_descriptors = ((),(),()) if e[0] != 4: # interrupt @@ -327,13 +310,12 @@ return True
-#import gobject -# FIXME: Does not work well with SSL, data may be "forgotten" in SSL buffer class GlibIdleQueue(IdleQueue): ''' Extends IdleQueue to use glib io_add_wath, instead of select/poll In another 'non gui' implementation of Gajim IdleQueue can be used safetly. ''' + def _init_idle(self): ''' Creates a dict, which maps file/pipe/sock descriptor to glib event id
Modified: trunk/src/common/xmpp/transports_nb.py =================================================================== --- trunk/src/common/xmpp/transports_nb.py 2008-12-31 14:04:42 UTC (rev 10932) +++ trunk/src/common/xmpp/transports_nb.py 2009-01-03 16:34:58 UTC (rev 10933) @@ -73,8 +73,8 @@
#: size of the buffer which reads data from server # if lower, more stanzas will be fragmented and processed twice -# but GUI will freeze less -RECV_BUFSIZE = 8192 +RECV_BUFSIZE = 32768 # 2x maximum size of ssl packet, should be plenty +#RECV_BUFSIZE = 16 # FIXME: (#2634) gajim breaks with this setting: it's inefficient but should work.
DATA_RECEIVED='DATA RECEIVED' DATA_SENT='DATA SENT' @@ -201,8 +201,6 @@ self.on_receive = None return self.on_receive = recv_handler - log.info('on_receive callback set to %s' % - self.on_receive.__name__ if self.on_receive else None)
def tcp_connecting_started(self): self.set_state(CONNECTING) @@ -371,8 +369,6 @@ if self.get_state() == CONNECTING: log.info('%s socket wrapper connected' % id(self)) self.idlequeue.remove_timeout(self.fd) - # We are only interested in stream errors right now - # _xmpp_connect_machine will take care of further plugging self._plug_idle(writable=False, readable=False) self.peerhost = self._sock.getsockname() if self.proxy_dict: @@ -443,6 +439,7 @@ self._do_send() else: self.sendqueue.append(r) + self._plug_idle(writable=True, readable=True)
def encode_stanza(self, stanza):
Modified: trunk/src/gajim.py =================================================================== --- trunk/src/gajim.py 2008-12-31 14:04:42 UTC (rev 10932) +++ trunk/src/gajim.py 2009-01-03 16:34:58 UTC (rev 10933) @@ -2862,7 +2862,11 @@ try: gajim.idlequeue.process() except Exception: - gobject.timeout_add(200, self.process_connections) + # Otherwise, an exception will stop our loop + if gajim.idlequeue.__class__ == idlequeue.GlibIdleQueue: + gobject.timeout_add_seconds(2, self.process_connections) + else: + gobject.timeout_add(200, self.process_connections) raise return True # renew timeout (loop for ever)
@@ -3107,9 +3111,15 @@ else: gajim.log.setLevel(None)
- # GObjectIdleQueue is currently broken with ssl. Use good old select - gajim.idlequeue = idlequeue.SelectIdleQueue() - + # pygtk2.8+ on win, breaks io_add_watch. + # We use good old select.select() + if os.name == 'nt': + gajim.idlequeue = idlequeue.SelectIdleQueue() + else: + # in a nongui implementation, just call: + # gajim.idlequeue = IdleQueue() , and + # gajim.idlequeue.process() each foo miliseconds + gajim.idlequeue = idlequeue.GlibIdleQueue() # resolve and keep current record of resolved hosts gajim.resolver = resolver.get_resolver(gajim.idlequeue) gajim.socks5queue = socks5.SocksQueue(gajim.idlequeue, @@ -3261,7 +3271,10 @@ self.last_ftwindow_update = 0
gobject.timeout_add(100, self.autoconnect) - gobject.timeout_add(200, self.process_connections) + if gajim.idlequeue.__class__ == idlequeue.GlibIdleQueue: + gobject.timeout_add_seconds(2, self.process_connections) + else: + gobject.timeout_add(200, self.process_connections) gobject.timeout_add_seconds(gajim.config.get( 'check_idle_every_foo_seconds'), self.read_sleepy)