Here a patch generated using debdiff.

I'm pretty new to Debian debug.
Hope this is more usefull.

-- 
Étienne Loks
diff -u gajim-0.13.4/debian/changelog gajim-0.13.4/debian/changelog
--- gajim-0.13.4/debian/changelog
+++ gajim-0.13.4/debian/changelog
@@ -1,3 +1,10 @@
+gajim (0.13.4-3.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Fix CPU high load when connecting first. Closes: #634880
+
+ -- Étienne Loks <etienne.l...@peacefrogs.net>  Wed, 20 Jul 2011 16:27:51 
+0200
+
 gajim (0.13.4-3) unstable; urgency=low
 
   * Fix a problem when canceling password keyring creation.
only in patch2:
unchanged:
--- gajim-0.13.4.orig/patches/fix-first_connection_cpu_load.patch
+++ gajim-0.13.4/patches/fix-first_connection_cpu_load.patch
@@ -0,0 +1,33 @@
+Index: gajim-0.13.4/src/common/xmpp/idlequeue.py
+===================================================================
+--- gajim-0.13.4.orig/src/common/xmpp/idlequeue.py     2011-07-21 
12:32:20.404426189 +0200
++++ gajim-0.13.4/src/common/xmpp/idlequeue.py  2011-07-20 16:32:59.747657971 
+0200
+@@ -362,20 +362,21 @@
+                       self.unplug_idle(fd)
+                       return False
+ 
++              if flags & IS_CLOSED:
++                      # io error, don't expect more events
++                      self.remove_timeout(obj.fd)
++                      self.unplug_idle(obj.fd)
++                      obj.pollend()
++                      return False
++
+               if flags & PENDING_READ:
+                       #print 'waiting read on %d, flags are %d' % (fd, flags)
+                       obj.pollin()
+                       return True
+ 
+-              elif flags & PENDING_WRITE:
++              if flags & PENDING_WRITE:
+                       obj.pollout()
+                       return True
+-
+-              elif flags & IS_CLOSED:
+-                      # io error, don't expect more events
+-                      self.remove_timeout(obj.fd)
+-                      self.unplug_idle(obj.fd)
+-                      obj.pollend()
+               return False
+ 
+       def process(self):
only in patch2:
unchanged:
--- gajim-0.13.4.orig/patches/series
+++ gajim-0.13.4/patches/series
@@ -0,0 +1 @@
+fix-first_connection_cpu_load.patch
only in patch2:
unchanged:
--- gajim-0.13.4.orig/src/common/xmpp/idlequeue.py
+++ gajim-0.13.4/src/common/xmpp/idlequeue.py
@@ -362,20 +362,21 @@
                        self.unplug_idle(fd)
                        return False
 
+               if flags & IS_CLOSED:
+                       # io error, don't expect more events
+                       self.remove_timeout(obj.fd)
+                       self.unplug_idle(obj.fd)
+                       obj.pollend()
+                       return False
+
                if flags & PENDING_READ:
                        #print 'waiting read on %d, flags are %d' % (fd, flags)
                        obj.pollin()
                        return True
 
-               elif flags & PENDING_WRITE:
+               if flags & PENDING_WRITE:
                        obj.pollout()
                        return True
-
-               elif flags & IS_CLOSED:
-                       # io error, don't expect more events
-                       self.remove_timeout(obj.fd)
-                       self.unplug_idle(obj.fd)
-                       obj.pollend()
                return False
 
        def process(self):
only in patch2:
unchanged:
--- gajim-0.13.4.orig/.pc/.quilt_series
+++ gajim-0.13.4/.pc/.quilt_series
@@ -0,0 +1 @@
+series
only in patch2:
unchanged:
--- gajim-0.13.4.orig/.pc/.version
+++ gajim-0.13.4/.pc/.version
@@ -0,0 +1 @@
+2
only in patch2:
unchanged:
--- gajim-0.13.4.orig/.pc/.quilt_patches
+++ gajim-0.13.4/.pc/.quilt_patches
@@ -0,0 +1 @@
+patches
only in patch2:
unchanged:
--- gajim-0.13.4.orig/.pc/applied-patches
+++ gajim-0.13.4/.pc/applied-patches
@@ -0,0 +1 @@
+fix-first_connection_cpu_load.patch
only in patch2:
unchanged:
--- 
gajim-0.13.4.orig/.pc/fix-first_connection_cpu_load.patch/src/common/xmpp/idlequeue.py
+++ 
gajim-0.13.4/.pc/fix-first_connection_cpu_load.patch/src/common/xmpp/idlequeue.py
@@ -0,0 +1,516 @@
+##   idlequeue.py
+##
+##   Copyright (C) 2006 Dimitur Kirov <dki...@gmail.com>
+##
+##   This program is free software; you can redistribute it and/or modify
+##   it under the terms of the GNU General Public License as published by
+##   the Free Software Foundation; either version 2, or (at your option)
+##   any later version.
+##
+##   This program is distributed in the hope that it will be useful,
+##   but WITHOUT ANY WARRANTY; without even the implied warranty of
+##   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##   GNU General Public License for more details.
+
+'''
+Idlequeues are Gajim's network heartbeat. Transports can be plugged as
+idle objects and be informed about possible IO.
+'''
+import os
+import select
+import logging
+log = logging.getLogger('gajim.c.x.idlequeue')
+
+# needed for get_idleqeue
+try:
+       import gobject
+       HAVE_GOBJECT = True
+except ImportError:
+       HAVE_GOBJECT = False
+
+# needed for idlecommand
+if os.name == 'nt':
+       from subprocess import * # python24 only. we ask this for Windows
+elif os.name == 'posix':
+       import fcntl
+
+FLAG_WRITE                     = 20 # write only
+FLAG_READ                      = 19 # read only
+FLAG_READ_WRITE        = 23 # read and write
+FLAG_CLOSE                     = 16 # wait for close
+
+PENDING_READ           = 3 # waiting read event
+PENDING_WRITE          = 4 # waiting write event
+IS_CLOSED                      = 16 # channel closed
+
+
+def get_idlequeue():
+       ''' Get an appropriate idlequeue '''
+       if os.name == 'nt':
+               # gobject.io_add_watch does not work on windows
+               return SelectIdleQueue()
+       else:
+               if HAVE_GOBJECT:
+                       # Gajim's default Idlequeue
+                       return GlibIdleQueue()
+               else:
+                       # GUI less implementation
+                       return SelectIdleQueue()
+
+
+class IdleObject:
+       '''
+               Idle listener interface. Listed methods are called by IdleQueue.
+       '''
+       def __init__(self):
+               self.fd = -1 #: filedescriptor, must be unique for each 
IdleObject
+
+       def pollend(self):
+               ''' called on stream failure '''
+               pass
+
+       def pollin(self):
+               ''' called on new read event '''
+               pass
+
+       def pollout(self):
+               ''' called on new write event (connect in sockets is a pollout) 
'''
+               pass
+
+       def read_timeout(self):
+               ''' called when timeout happened '''
+               pass
+
+
+class IdleCommand(IdleObject):
+       '''
+       Can be subclassed to execute commands asynchronously by the idlequeue.
+       Result will be optained via file descriptor of created pipe
+       '''
+       def __init__(self, on_result):
+               IdleObject.__init__(self)
+               # how long (sec.) to wait for result ( 0 - forever )
+               # it is a class var, instead of a constant and we can override 
it.
+               self.commandtimeout = 0
+               # when we have some kind of result (valid, ot not) we call this 
handler
+               self.result_handler = on_result
+               # if it is True, we can safetely execute the command
+               self.canexecute = True
+               self.idlequeue = None
+               self.result =''
+
+       def set_idlequeue(self, idlequeue):
+               self.idlequeue = idlequeue
+
+       def _return_result(self):
+               if self.result_handler:
+                       self.result_handler(self.result)
+               self.result_handler = None
+
+       def _compose_command_args(self):
+               return ['echo', 'da']
+
+       def _compose_command_line(self):
+               ''' return one line representation of command and its arguments 
'''
+               return  reduce(lambda left, right: left + ' ' + right,
+                       self._compose_command_args())
+
+       def wait_child(self):
+               if self.pipe.poll() is None:
+                       # result timeout
+                       if self.endtime < self.idlequeue.current_time():
+                               self._return_result()
+                               self.pipe.stdout.close()
+                               self.pipe.stdin.close()
+                       else:
+                               # child is still active, continue to wait
+                               self.idlequeue.set_alarm(self.wait_child, 0.1)
+               else:
+                       # child has quit
+                       self.result = self.pipe.stdout.read()
+                       self._return_result()
+                       self.pipe.stdout.close()
+                       self.pipe.stdin.close()
+
+       def start(self):
+               if not self.canexecute:
+                       self.result = ''
+                       self._return_result()
+                       return
+               if os.name == 'nt':
+                       self._start_nt()
+               elif os.name == 'posix':
+                       self._start_posix()
+
+       def _start_nt(self):
+               # if gajim is started from noninteraactive shells stdin is 
closed and
+               # cannot be forwarded, so we have to keep it open
+               self.pipe = Popen(self._compose_command_args(), stdout=PIPE,
+                       bufsize = 1024, shell = True, stderr = STDOUT, stdin = 
PIPE)
+               if self.commandtimeout >= 0:
+                       self.endtime = self.idlequeue.current_time() + 
self.commandtimeout
+                       self.idlequeue.set_alarm(self.wait_child, 0.1)
+
+       def _start_posix(self):
+               self.pipe = os.popen(self._compose_command_line())
+               self.fd = self.pipe.fileno()
+               fcntl.fcntl(self.pipe, fcntl.F_SETFL, os.O_NONBLOCK)
+               self.idlequeue.plug_idle(self, False, True)
+               if self.commandtimeout >= 0:
+                       self.idlequeue.set_read_timeout(self.fd, 
self.commandtimeout)
+
+       def end(self):
+               self.idlequeue.unplug_idle(self.fd)
+               try:
+                       self.pipe.close()
+               except:
+                       pass
+
+       def pollend(self):
+               self.idlequeue.remove_timeout(self.fd)
+               self.end()
+               self._return_result()
+
+       def pollin(self):
+               try:
+                       res = self.pipe.read()
+               except Exception, e:
+                       res = ''
+               if res == '':
+                       return self.pollend()
+               else:
+                       self.result += res
+
+       def read_timeout(self):
+               self.end()
+               self._return_result()
+
+
+class IdleQueue:
+       '''
+       IdleQueue provide three distinct time based features. Uses select.poll()
+
+               1. Alarm timeout: Execute a callback after foo seconds
+               2. Timeout event: Call read_timeout() of an plugged object if a 
timeout
+               has been set, but not removed in time.
+               3. Check file descriptor of plugged objects for read, write and 
error
+               events
+       '''
+       # (timeout, boolean)
+       # Boolean is True if timeout is specified in seconds, False means 
miliseconds
+       PROCESS_TIMEOUT = (100, False)
+
+       def __init__(self):
+               self.queue = {}
+
+               # when there is a timeout it executes obj.read_timeout()
+               # timeout is not removed automatically!
+               # {fd1: {timeout1: func1, timeout2: func2}}
+               # timout are unique (timeout1 must be != timeout2)
+               # If func1 is None, read_time function is called
+               self.read_timeouts = {}
+
+               # cb, which are executed after XX sec., alarms are removed 
automatically
+               self.alarms = {}
+               self._init_idle()
+
+       def _init_idle(self):
+               ''' Hook method for subclassed. Will be called by __init__. '''
+               self.selector = select.poll()
+
+       def set_alarm(self, alarm_cb, seconds):
+               '''
+               Sets up a new alarm. alarm_cb will be called after specified 
seconds.
+               '''
+               alarm_time = self.current_time() + seconds
+               # almost impossible, but in case we have another alarm_cb at 
this time
+               if alarm_time in self.alarms:
+                       self.alarms[alarm_time].append(alarm_cb)
+               else:
+                       self.alarms[alarm_time] = [alarm_cb]
+               return alarm_time
+
+       def remove_alarm(self, alarm_cb, alarm_time):
+               '''
+               Removes alarm callback alarm_cb scheduled on alarm_time.
+               Returns True if it was removed sucessfully, otherwise False
+               '''
+               if not alarm_time in self.alarms:
+                       return False
+               i = -1
+               for i in range(len(self.alarms[alarm_time])):
+                       # let's not modify the list inside the loop
+                       if self.alarms[alarm_time][i] is alarm_cb:
+                               break
+               if i != -1:
+                       del self.alarms[alarm_time][i]
+                       if self.alarms[alarm_time] == []:
+                               del self.alarms[alarm_time]
+                       return True
+               else:
+                       return False
+
+       def remove_timeout(self, fd, timeout=None):
+               ''' Removes the read timeout '''
+               log.info('read timeout removed for fd %s' % fd)
+               if fd in self.read_timeouts:
+                       if timeout:
+                               if timeout in self.read_timeouts[fd]:
+                                       del(self.read_timeouts[fd][timeout])
+                               if len(self.read_timeouts[fd]) == 0:
+                                       del(self.read_timeouts[fd])
+                       else:
+                               del(self.read_timeouts[fd])
+
+       def set_read_timeout(self, fd, seconds, func=None):
+               '''
+               Sets a new timeout. If it is not removed after specified 
seconds,
+               func or obj.read_timeout() will be called.
+
+               A filedescriptor fd can have several timeouts.
+               '''
+               log_txt = 'read timeout set for fd %s on %s seconds' % (fd, 
seconds)
+               if func:
+                       log_txt += ' with function ' + str(func)
+               log.info(log_txt)
+               timeout = self.current_time() + seconds
+               if fd in self.read_timeouts:
+                       self.read_timeouts[fd][timeout] = func
+               else:
+                       self.read_timeouts[fd] = {timeout: func}
+
+       def _check_time_events(self):
+               '''
+               Execute and remove alarm callbacks and execute func() or 
read_timeout()
+               for plugged objects if specified time has ellapsed.
+               '''
+               log.info('check time evs')
+               current_time = self.current_time()
+
+               for fd, timeouts in self.read_timeouts.items():
+                       if fd not in self.queue:
+                               self.remove_timeout(fd)
+                               continue
+                       for timeout, func in timeouts.items():
+                               if timeout > current_time:
+                                       continue
+                               if func:
+                                       log.debug('Calling %s for fd %s' % 
(func, fd))
+                                       func()
+                               else:
+                                       log.debug('Calling read_timeout for fd 
%s' % fd)
+                                       self.queue[fd].read_timeout()
+                               self.remove_timeout(fd, timeout)
+
+               times = self.alarms.keys()
+               for alarm_time in times:
+                       if alarm_time > current_time:
+                               continue
+                       if alarm_time in self.alarms:
+                               for callback in self.alarms[alarm_time]:
+                                       callback()
+                               if alarm_time in self.alarms:
+                                       del(self.alarms[alarm_time])
+
+       def plug_idle(self, obj, writable=True, readable=True):
+               '''
+               Plug an IdleObject into idlequeue. Filedescriptor fd must be 
set.
+
+               :param obj: the IdleObject
+               :param writable: True if obj has data to sent
+               :param readable: True if obj expects data to be reiceived
+               '''
+               if obj.fd == -1:
+                       return
+               if obj.fd in self.queue:
+                       self.unplug_idle(obj.fd)
+               self.queue[obj.fd] = obj
+               if writable:
+                       if not readable:
+                               flags = FLAG_WRITE
+                       else:
+                               flags = FLAG_READ_WRITE
+               else:
+                       if readable:
+                               flags = FLAG_READ
+                       else:
+                               # when we paused a FT, we expect only a close 
event
+                               flags = FLAG_CLOSE
+               self._add_idle(obj.fd, flags)
+
+       def _add_idle(self, fd, flags):
+               ''' Hook method for subclasses, called by plug_idle '''
+               self.selector.register(fd, flags)
+
+       def unplug_idle(self, fd):
+               ''' Removed plugged IdleObject, specified by filedescriptor fd. 
 '''
+               if fd in self.queue:
+                       del(self.queue[fd])
+                       self._remove_idle(fd)
+
+       def current_time(self):
+               from time import time
+               return time()
+
+       def _remove_idle(self, fd):
+               ''' Hook method for subclassed, called by unplug_idle '''
+               self.selector.unregister(fd)
+
+       def _process_events(self, fd, flags):
+               obj = self.queue.get(fd)
+               if obj is None:
+                       self.unplug_idle(fd)
+                       return False
+
+               if flags & PENDING_READ:
+                       #print 'waiting read on %d, flags are %d' % (fd, flags)
+                       obj.pollin()
+                       return True
+
+               elif flags & PENDING_WRITE:
+                       obj.pollout()
+                       return True
+
+               elif flags & IS_CLOSED:
+                       # io error, don't expect more events
+                       self.remove_timeout(obj.fd)
+                       self.unplug_idle(obj.fd)
+                       obj.pollend()
+               return False
+
+       def process(self):
+               '''
+               Process idlequeue. Check for any pending timeout or alarm 
events.
+               Call IdleObjects on possible and requested read, write and 
error events
+               on their file descriptors.
+
+               Call this in regular intervals.
+               '''
+               if not self.queue:
+                       # check for timeouts/alert also when there are no 
active fds
+                       self._check_time_events()
+                       return True
+               try:
+                       waiting_descriptors = self.selector.poll(0)
+               except select.error, e:
+                       waiting_descriptors = []
+                       if e[0] != 4: # interrupt
+                               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
+
+       This class exisists for the sake of gtk2.8 on windows, which
+       doesn't seem to support io_add_watch properly (yet)
+       '''
+       def _init_idle(self):
+               '''
+               Creates a dict, which maps file/pipe/sock descriptor to glib 
event id
+               '''
+               self.read_fds = {}
+               self.write_fds = {}
+               self.error_fds = {}
+
+       def _add_idle(self, fd, flags):
+               ''' this method is called when we plug a new idle object.
+               Remove descriptor to read/write/error lists, according flags
+               '''
+               if flags & 3:
+                       self.read_fds[fd] = fd
+               if flags & 4:
+                       self.write_fds[fd] = fd
+               self.error_fds[fd] = fd
+
+       def _remove_idle(self, fd):
+               ''' this method is called when we unplug a new idle object.
+               Remove descriptor from read/write/error lists
+               '''
+               if fd in self.read_fds:
+                       del(self.read_fds[fd])
+               if fd in self.write_fds:
+                       del(self.write_fds[fd])
+               if fd in self.error_fds:
+                       del(self.error_fds[fd])
+
+       def process(self):
+               if not self.write_fds and not self.read_fds:
+                       self._check_time_events()
+                       return True
+               try:
+                       waiting_descriptors = 
select.select(self.read_fds.keys(),
+                               self.write_fds.keys(), self.error_fds.keys(), 0)
+               except select.error, e:
+                       waiting_descriptors = ((),(),())
+                       if e[0] != 4: # interrupt
+                               raise
+               for fd in waiting_descriptors[0]:
+                       q = self.queue.get(fd)
+                       if q:
+                               q.pollin()
+               for fd in waiting_descriptors[1]:
+                       q = self.queue.get(fd)
+                       if q:
+                               q.pollout()
+               for fd in waiting_descriptors[2]:
+                       q = self.queue.get(fd)
+                       if q:
+                               q.pollend()
+               self._check_time_events()
+               return True
+
+
+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.
+       '''
+       # (timeout, boolean)
+       # Boolean is True if timeout is specified in seconds, False means 
miliseconds
+       PROCESS_TIMEOUT = (2, True)
+
+       def _init_idle(self):
+               '''
+               Creates a dict, which maps file/pipe/sock descriptor to glib 
event id
+               '''
+               self.events = {}
+               # time() is already called in glib, we just get the last value
+               # overrides IdleQueue.current_time()
+               self.current_time = gobject.get_current_time
+
+       def _add_idle(self, fd, flags):
+               ''' this method is called when we plug a new idle object.
+               Start listening for events from fd
+               '''
+               res = gobject.io_add_watch(fd, flags, self._process_events,
+                       priority=gobject.PRIORITY_LOW)
+               # store the id of the watch, so that we can remove it on unplug
+               self.events[fd] = res
+
+       def _process_events(self, fd, flags):
+               try:
+                       return IdleQueue._process_events(self, fd, flags)
+               except Exception:
+                       self._remove_idle(fd)
+                       self._add_idle(fd, flags)
+                       raise
+
+       def _remove_idle(self, fd):
+               ''' this method is called when we unplug a new idle object.
+               Stop listening for events from fd
+               '''
+               if not fd in self.events:
+                       return
+               gobject.source_remove(self.events[fd])
+               del(self.events[fd])
+
+       def process(self):
+               self._check_time_events()
+
+
+# vim: se ts=3:

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to