Maemo 0.4.11.11-1
[aptitude] / README.THREADS
1   The basic threading philosophy followed in aptitude can be
2 summarized thus: "if you aren't sure it's safe, do it in the main
3 thread".  The mechanism for doing so is cwidget::toplevel::post_event
4 (cwidget/toplevel.h), which places a callback object into the global
5 event queue and wakes the main thread (if necessary).  You can also
6 take a global lock to get the same effect...but it's really
7 recommended that you use the event queue.
8
9   The actual threading constructs used are the pthread wrappers in
10 cwidget/generic/threads.h (and also cwidget/generic/event_queue.h).
11
12   Background threads are spawned to do long-running operations, but they
13 generally only access data that is "owned" by the thread.  More
14 details on the currently existing background threads below.
15
16   These threads generally take some sort of "continuation" object
17 that's invoked when the background process is finished; it's expected
18 that this object will probably post some sort of event to the main
19 thread.
20
21   Things that you might thank are threadsafe but aren't include:
22
23   * sigc++ objects.  Not only do you have to watch out for manual
24     additions and deletions to connection lists during invocation, you
25     also have to watch out for automatic invalidation of slots at any
26     time.  Best practice here is to confine sigc++ access to the main
27     thread.
28
29   * Smart pointers.  Most smart pointers that aptitude uses are NOT
30     threadsafe.  This means that *EVEN READ-ONLY ACCESS* from another
31     thread will cause horrible ghastly problems that you don't even
32     want to think about.  At the moment it's almost never necessary to
33     pass these between threads, so it's not a big deal; the exception
34     is the problem resolver's solution objects (and the shared trees
35     contained inside them), which are dealt with by doing a deep copy
36     of the object. (see resolver_manager::do_get_solution)
37
38     The reason this is the case is basically that the pthread
39     abstraction doesn't give you a fast lock for low-contention
40     situations -- adding locking around the reference counts of set
41     tree nodes made the overall resolver take 50% longer to run in
42     single-threaded mode!  I'm not eager to add nonportable threading
43     constructs, so I decided to see whether it was possible to just be
44     very careful about handling reference-counted objects.
45
46 Existing background threads:
47
48   * The cwidget library creates threads to handle keyboard input,
49     certain asynchronous signals, and timed events.  You generally
50     don't need to worry about these.
51
52   * Downloads are performed by a background thread.  In keeping with
53     the overall philosophy, only the actual download is handled in
54     this way -- the setup of the download and any actions taken once
55     it completes are handled by the main thread.  The gatekeeper for
56     downloads is in download_thread.cc; it provides the basic thread
57     harness, as well as a convenience class that forwards the various
58     download messages to a foreground progress meter.  (these are
59     basically inter-thread RPC calls, and they block the download
60     thread until the progress meter's method call returns a value)
61
62   * The problem resolver runs in a background thread.  This thread
63     always exists, even when there is no resolver (in which case it
64     will just sleep); the foreground thread can post jobs to it, and
65     will also stop the resolver whenever its state needs to be
66     modified (for instance, if the rejected set is changed).  The
67     interface for this is in src/generic/resolver_manager.cc.