The Threading package includes the runnable classes and the thread attribute classes.
The Threading package runnable objects are implemented using a common C++ design technique called the handle-body idiom. Each runnable instance consists of a protected body instance with one or more public handle instances that reference it. The hierarchy of runnable classes is shown in Figure 2.
A runnable object is reference-counted. Each runnable body instance keeps a count of the number of handles that currently reference it. A runnable object is deleted when the last handle that references the body is deleted.
The public interface for a runnable is included in its handle classes. Many of the public functions in a handle simply forward control to a corresponding protected function in the body class.
You can find additional information regarding the handle-body idiom and reference-counting in the Smart Pointer package.
Many runnable objects supply two different handle classes-one that defines an interface intended for use by outside threads and one that defines an interface that can only be used by the thread running inside the runnable object. Other runnable functions do not have inside or outside access restrictions and are defined in both the internal and external handle classes.
Outside threads-The RWRunnable and RWThread handles give access to functions that outside threads use to manipulate the corresponding runnable, such as requestInterrupt() or resume().
Inside threads-The RWRunnableSelf and RWThreadSelf handles give access to functions that can only be used by the thread running inside the runnable, such as serviceInterrupt() or yield().
Internal and external handle instances-An internal handle instance can be converted to an external handle instance and vice-versa, but any attempt to violate the thread access restrictions imposed by the separate interfaces generally results in an RWTHRIllegalAccess exception.
Empty handles-A runnable handle instance is not required to reference a body-handles can be constructed in an empty state. Many of the functions provided by the handle class cannot be used if the handle instance is empty. Calls to functions that are normally forwarded to a body instance produce an RWTHRInvalidPointer exception if called on an empty handle. You can test a handle to see if it is empty by using the isValid() member function.
Body instances-The runnable handle classes do not have any public constructors that build a corresponding body instance. Body instances are constructed by calling one of the static make() functions included in each handle class. These functions dynamically allocate the appropriate body class instance on the heap, and return a temporary handle instance that has been bound to the new body.
The runnable body classes are not publicly accessible. These classes can only be accessed and constructed using functions defined by the runnable handle classes.
The thread pool handle class RWThreadPool is not a runnable. It is included in this hierarchy because of its relationship to RWServerPool.
All of the thread attributes supported by the Threading package are captured within instances of the RWThreadAttribute class, as shown in Figure 3.
Figure 4 shows the IOU class hierarchy. All but one of these classes are in the Interthread Communication package, which implements the framework for the IOU functionality. The hierarchy is duplicated here, because the piece that makes IOUs usable is the Threading package class RWTThreadEscrowImp. This class has the mechanisms for synchronizing multithread access to the result and blocking threads that have attempted to redeem the result before it has been supplied.
©Copyright 2000, Rogue Wave Software, Inc.
Contact Rogue Wave about documentation or support issues.