Created by James Westby on 2010-04-07 and last modified on 2010-04-07
Get this branch:
bzr branch lp:~james-w/gwibber/fix-threading
Only James Westby can upload to this branch. If you are James Westby please log in for upload directions.

Branch merges

Related bugs

Related blueprints

Branch information

James Westby

Recent revisions

708. By James Westby on 2010-04-07

Use Processes rather than Threads to avoid gobject.threads_init().

Calling gobject.threads_init() if you have multiple threads is absolutely
the right thing to do.

However, it creates a pipe(2) and sets up watches on this so that one thread
can wake another.

Python's multiprocessing spawns processes, but it only uses fork(2) to do this,
meaning that the children will inherit the parent's file descriptors.

Therefore if you combine threads, gobject and multiprocessing in one app
the children will be able to interfere with the parent using these fds.

When using some glib functions in the child (such as calling gnome-keyring)
it will write things to the pipe to wake other threads, but as the pipe is
shared it can wake the wrong one.

In addition when the child closes it can leave the parent in a confused state,
where it continually polls the pipe, taking up all the CPU.

There are several things you can do about this:

  * Not do any glib stuff involving watches or timeouts etc. in the child.
  * Not use threads in the parent and so not call gobject.threads_init()
  * Not use multiprocessing and do everything in threads.

The other alternative would be to properly isolate the children. glib
goes some way towards this by allowing you to change the GMainContext
for a thread, and you could use that in the child processes, except:

  * You can't do this from python currently.
  * Not all library code may use this properly and so cause issues anyway.

Here we took the approach to not use any threads. Anything that didn't
need to be a thread was made not to be one (Dispatcher), and anything
that needed to run in parallel was changed to use multiprocessing (MapAsync,
couchdb Monitor). This means we can delete the gobject.threads_init()
call and so avoid the pipe that was inherited and the bad behaviour.
There may be any number of other issues with the children sharing too
much global state of the parent though.

Or, in other words, global state bad.

707. By Ken VanDine on 2010-04-05

Reset refresh interval to pick up changes in settings

706. By Ryan Paul on 2010-04-03

Automatically purge messages when the db gets too big

705. By Ryan Paul on 2010-04-03

Fixed color handling regression in accounts

704. By Ryan Paul on 2010-04-03

Respect full name preference in notification bubbles

703. By Ken VanDine on 2010-03-31

Raise account dialog when password is missing from the keyring

702. By Ken VanDine on 2010-03-31

[merged] highlight accounts that don't have passwords set in the keyring that should be

701. By Ken VanDine on 2010-03-31

Use gconf to store local settings instead of desktopcouch

700. By Ken VanDine on 2010-03-31

Set the password even if we don't use the keyring

699. By Ken VanDine on 2010-03-31

moved URLs for translations and questions to variables

Branch metadata

Branch format:
Branch format 7
Repository format:
Bazaar repository format 2a (needs bzr 1.16 or later)
Stacked on:
This branch contains Public information 
Everyone can see this information.