New Layout: Threading Model
Updated: March 10, 1998This document describes the threading model for the nglayout engine and related services.
Overview
There is one thread per top level window, called the UI thread. This thread receives events from the native window systems' event system and distributes the events to the appropriate handles (widgets, callbacks, etc.) This thread does not do network I/O (the network library manages a collection of threads to do network I/O). Modal windows are handled by having this thread block while waiting for a response from a modal dialog.Layout occurs on this thread, including the original parsing and processing of a document load, and subsequent incremental layout operations which include resize reflow, dom activity, and editing.
To prevent the UI thread from being unresponsive during large scale layout orjavascript computations, each of these engines has an interface
which provides a progress call back. The application can choose to
abort the layout or javascript execution based on it's own criteria. H
ere is the proposed interface:
enum nsExecProgressStatus { eExecProgressStatus_Continue = 0, eExecProgressStatus_Stop };
class nsIExecProgress : public nsISupports { public: virtual nsExecProgressStatus Update() = 0; };At some reasonable rate the Update procedure will be called to give the outer invocation a chance to abort or continue the execution.
For systems which do not support pre-emptive threading, this callback is also an opportune time to yield the processor to other threads.
The above API is speculative.
Examples
Example 1: A javascript event handler sits and spins for an eternity. The javascript evaluation call takes a pointer to an implementation of nsIExecProgress. Periodically the javascript evaluator will invoke the interface to see if execution should continue. The UI thread which invoked the script can set a timeout, say a couple of seconds, and after the time has expired can abort the evaluation (or put up a modal dialog and see if the user wants the operation to continue; it's really up to the outer context to decide what to do).Example 2: A document is loading and the user clicks on a link to go somewhere else before the document is finished loading. In this case, the UI thread needs enough cycles for the cursor to be responsive and for the user gesture to be translated and mapped into aborting the document load and moving to a new location. Layout will also take a pointer to an implementation of nsIExecProgress and will periodically invoke it to see if layout should continue.
Example 3: A dcoument is loading and the user hits the stop, back, forward, etc. button. This is really the same as example 2.
Netlib
Because the networking I/O is now being done on a seperate thread, the netlib1 library will need modifications. There are two areas:- First, any usage of the MWContext by the netlib code needs to be removed and replaced with a "NetContext" abstraction. This way an environment using netlib can provide the necessary data for ftp/gopher passwords, and deal with the security dialog issues.
- Second, when data is ready to be consumed by a netlib presentation stream handler, we need to get the data from the netlib thread to the consuming thread.
Other Libraries
The rule of the day is: No global data that isn't thread safe. Thr reason is that once you have multiple threads using these libraries (minimally there will be multiple UI threads) then you have to protect your global data with locks. Fortunately we have NSPR20 and it runs everywhere.list out each library and indicate how much work needs to be done