diff options
author | Daniel Burrows <dburrows@debian.org> | 2005-10-01 23:40:49 +0000 |
---|---|---|
committer | Daniel Burrows <dburrows@debian.org> | 2005-10-01 23:40:49 +0000 |
commit | db949f313eb10b747a875067623b89c47ee2b81d (patch) | |
tree | 95891553696a84cc382aa9a92bacdc88950361e1 /README.THREADS | |
parent | e5434a5aaf63b1602c81606824b94f0368e4aaa0 (diff) | |
download | aptitude-db949f313eb10b747a875067623b89c47ee2b81d.tar.gz |
[aptitude @ Import the Subversion repository into darcs.]
Diffstat (limited to 'README.THREADS')
-rw-r--r-- | README.THREADS | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/README.THREADS b/README.THREADS new file mode 100644 index 00000000..7d61b2f0 --- /dev/null +++ b/README.THREADS @@ -0,0 +1,67 @@ + The basic threading philosophy followed in aptitude can be +summarized thus: "if you aren't sure it's safe, do it in the main +thread". The mechanism for doing so is vscreen_post_event +(vscreen.cc), which places a callback object into the global event +queue and wakes the main thread (if necessary). You can also take a +global lock to get the same effect...but it's really recommended that +you use the event queue. + + The actual threading constructs used are the pthread wrappers in +src/generic/threads.h (and also src/generic/event_queue.h). + + Background threads are spawned to do long-running operations, but they +generally only access data that is "owned" by the thread. More +details on the currently existing background threads below. + + These threads generally take some sort of "continuation" object +that's invoked when the background process is finished; it's expected +that this object will probably post some sort of event to the main +thread. + + Things that you might thank are threadsafe but aren't include: + + * sigc++ objects. Not only do you have to watch out for manual + additions and deletions to connection lists during invocation, you + also have to watch out for automatic invalidation of slots at any + time. Best practice here is to confine sigc++ access to the main + thread. + + * Smart pointers. Most smart pointers that aptitude uses are NOT + threadsafe. This means that *EVEN READ-ONLY ACCESS* from another + thread will cause horrible ghastly problems that you don't even + want to think about. At the moment it's almost never necessary to + pass these between threads, so it's not a big deal; the exception + is the problem resolver's solution objects (and the shared trees + contained inside them), which are dealt with by doing a deep copy + of the object. (see resolver_manager::do_get_solution) + + The reason this is the case is basically that the pthread + abstraction doesn't give you a fast lock for low-contention + situations -- adding locking around the reference counts of set + tree nodes made the overall resolver take 50% longer to run in + single-threaded mode! I'm not eager to add nonportable threading + constructs, so I decided to see whether it was possible to just be + very careful about handling reference-counted objects. + +Existing background threads: + + * The vscreen library creates threads to handle keyboard input, + certain asynchronous signals, and timed events. You generally + don't need to worry about these. + + * Downloads are performed by a background thread. In keeping with + the overall philosophy, only the actual download is handled in + this way -- the setup of the download and any actions taken once + it completes are handled by the main thread. The gatekeeper for + downloads is in download_thread.cc; it provides the basic thread + harness, as well as a convenience class that forwards the various + download messages to a foreground progress meter. (these are + basically inter-thread RPC calls, and they block the download + thread until the progress meter's method call returns a value) + + * The problem resolver runs in a background thread. This thread + always exists, even when there is no resolver (in which case it + will just sleep); the foreground thread can post jobs to it, and + will also stop the resolver whenever its state needs to be + modified (for instance, if the rejected set is changed). The + interface for this is in src/generic/resolver_manager.cc. |