Warning: The content of this article may be out of date. It was last updated in 2001.
Necko's primary interfaces are NOT thread safe. There has not yet been a need to make Necko entirely thread safe as most of Mozilla (and especially most of Gecko) run only on the main/primordial thread. In the future, Necko may be made thread safe to support changes to Gecko that would put some other processing work on background threads (eg. multithreaded image decoding).
However, most Necko protocols utilize background threads. Background threads are used to manage all I/O operations (with the exception of few cases).
Most simple protocol handlers (eg. file, finger, datetime) do not worry about threading issues. The internal I/O interfaces default to proxying all callbacks to the main thread. This keeps simple protocol handlers simple :-)
More complex protocol handlers (eg. http, ftp) operate partially on the background threads to improve performance. For example, the http protocol handler has code that runs on the socket transport thread to kick off pending requests well before the main thread would get around to doing so.
Socket connections are processed on a single background thread. This thread is controlled by the nsSocketTransportService. It sits in a loop, polling a list of sockets. When a socket can be read, the socket's listener is notified either synchronously (on the same thread) or asynchronously via a nsIStreamListenerProxy impl.
File I/O is processed via a thread pool that has between 1 and 4 threads. These threads are controlled by the nsFileTransportService. Each file transport object is given time on one of the file transport threads. During which it reads (writes) until its buffers are full (empty). Once at the limit of its buffers, it yields the thread to another pending file transport object.
As with the socket transport thread, the nsIStreamListener passed to a file transport's AsyncRead method can operate partially on the file transport's thread before proxying data to the main thread.
The file transport is confusingly named since it is not restricted to loading files. It simply promises to read from a nsIInputStream (or write to a nsIOutputStream) on a background thread. The implementation of the stream should be blocking; however, there is limited support for non-blocking streams.
Cached page loads, file URL loads, and jar URL loads all utilize the file transport service. The jar protocol handler, for rexample, passes a special nsIInputStream impl that does gzip decoding on the fly.
On most platforms DNS requests a processed on a background thread. However, the details of the implementation are heavily platform dependent. For example, on XP_WIN an invisible window is created with a message pump on a background thread for processing WSA asynchronous DNS events. In this way, Necko takes advantage of the platforms specific routines for DNS lookups. The default implementation does not spawn a worker thread, and instead simply calls PR_GetIPNodeByName (essentially equivalent to gethostbyname).