FIGUE
*Design *Boxes *Combinator *Formatting *Geometry *Reuse
*Selections *Paths *Concurrency *Exception *Interaction *Utility
*Resource *Drawing *Incremental *Customize *Various

Concurrency

The API cross references give an immediate access to relevant interfaces and classes.

* Guarded Methods and Thread Conditions

Guarded methods are those that block if the target object is not in a state in which the associated actions can be executed, later proceeding when conditions change. This is not a busy-wait loop, so all methods that cause relevant state changes must provide notifications to wake up waiting threads.

GUARDED METHOD

Thread conditions encapsulate the waits and notifications used in guarded methods.

THREAD CONDITIONS

A typical guarded method implementation looks like :

  public void executeWhenConditionHold() {
    synchronized ( _condition ) {
      synchronized ( this ) {
	if ( conditionHold() ) {
	  // do actions
	 break;
	}
      }
      _condition.await();
    }
    // notify relevant state change
    _condition.signal();
    _otherCondition.signal();
    ...
  }
	  

* Notifying Thread State

Notifying thread state is a concept for tracking and notifying about thread state changes. Its main use is to express conditions used in guarded methods. A state knows about its current thread status (drawing, formatting, building), the actions that could be initiated (start action),those that could be stopped (end action), and the resulting new state. The notifier encapsulates the state and awake the observer on relevant state changes (i.e. after end action).

THREAD STATE

Currently, we have adopt the main following rules (these constraints are dictate by the synchronization of the threads) :

  • We can not initiate an update of the glyphs when there is only drawing or formatting operations in background.
  • We can not initiate a formatting as long as the current drawing operation is not done.
  • There is two special states:
    • An invalid one where we fall after a bad transition. For the moment, the only purpose of this state is in reporting a fatal error. But it could be used in close futur as a mean for error recovery (i.e. resynchronization of faultly tasks).
    • A busy one which is virtual, as we only need to hold on the lock in the inactive state.

These rules are reflect by the automata:

THREAD STATE

* Thread

A thread is a thread of execution in a program. We have a thread for each basic task, i.e. building, formatting and drawing.Each thread has a condition describing its right state. The notifying thread state wakes up the threads after each relevant transition.

THREAD
The following template method describes the activation scheme :
  public final void run() {
    synchronized ( _condition ) {
      while ( true ) {
	if ( isInRightState() ) {
	  execute();
	}
	else {
	  _condition.await();
	}
      }
    }
  }
	  

* Thread Synchronization

The thread launching and awakening are synchronized throught using the notifying thread state at the task level. The format status is used at glyph level when a task must wait for the advance of another. Typically, the draw thread will wait for advance of the format thread when he finds a dirty glyph. The format thread will wait for advance of the build thread when he finds an unstable glyph. The proceed status is used when building an huge box structure and allows intermediate drawing, when we know that a particular box will not changed (sounds to us like "Netscape Effect"). The new status is a kind of dirty status introduced just for incrementality.

FORMAT STATUS

The next diagram shows how the depth first search from left to right used by the threads introduce constraints in synchronization. This scheme also explains some forbidden state transitions in the previous automata, since each thread assumes from the previous no backtrack in the done work. For example, when a build cycle is done we must wait for the end of the current drawing and formatting actions before a new build cycle could be initiate.

THREAD SYNCHRONIZATION

* Intermediate Drawing

When we are building the global box structure in batch mode (by opposition to interactive updates) we want to give the user a first result as soon as possible. To do so, we check during formatting if the glyph and all ancestors are unconditionnal. If true, we know that we could compute an intermediate size and start drawing. As this process costs a lot and may involve many redundant computations, we first estimate the height of formatted children and notify advance only when a sufficient height is done. As soon as, a glyph is ready for an intermediate drawing it is marked with proceed status. For the moment, only vertical, change graphical context and decorated glyph of which the component is unconditionnal are unconditionnal. For efficiency purpose, we are not concerned with neither atom nor horizontal.

INTERMEDIATE DRAWING

* API Cross References


*Design *Boxes *Combinator *Formatting *Geometry *Reuse
*Selections *Paths *Concurrency *Exception *Interaction *Utility
*Resource *Drawing *Incremental *Customize *Various

Comments or suggestions?
Need some help?
Copyright ©1998 INRIA
Last updated 5 October 1998 by Bruno Conductier
FIGUE