3.8.2 Compound Devices

Compound devices are very common in the financial services industry. For the purposes of this discussion, there are three types of compound devices:

The first of these types has no special significance from the XFS point of view. Each of the devices is managed as a separate logical and physical device, and the system configuration issues (e.g., making sure that devices that are packaged together are assigned to the same workstation) are left to application utilities outside the scope of this specification.

The latter two types are treated identically in an XFS system. When any one of a set of interdependent logical devices that forms a compound device is locked, all the other logical devices in that compound device are also implicitly locked on behalf of the requesting application. (The specific policy is described below.) If the same application (see the discussion of “application identity” below and in Section 3.5) explicitly requests a lock of another of these logical devices, the lock is granted. In order to allow the application to “know” that the devices are part of a compound device, and therefore interdependent, the WFSLock function returns an array of service handles, defining the set of other devices within the compound device that are now explicitly locked by the application. This allows the application to manage its use of these devices accordingly. Normally, it must use them in a strictly sequential manner to avoid any possible conflicts, but if it has some special knowledge of how the devices are related, it may be able to multiplex requests in some ways.

Note that an application can also determine whether a device is compound by using the device capabilities query function of WFSGetInfo.

There are many different ways in which programmers can make use of multiple threads and/or processes in financial applications. Each WOSA/XFS service can be controlled from its own thread; all services can be controlled from a single thread, with other threads/processes used for other application functions; several identical threads can handle all open services as needed; etc. In some of these models, the “user” of a service could be considered to be the process as a whole; in other models, the “user” is a single thread. The WOSA/XFS design allows for both models by providing the programmer the capability to explicitly control the “identity” of an application. The programmer can make all the threads in a process appear to a service provider as one “application,” identify each thread as a different “application,” or create some hybrid of these approaches, allowing interdependent compound devices to be managed correctly no matter what application architecture is used.

In order to allow this flexibility in application architecture, the “identity” of an application can optionally be managed explicitly using the concept of application handles. An application handle (hApp) is created using the WFSCreateAppHandle function, and is guaranteed unique within the system. The WFSOpen function takes an optional application handle parameter which is bound to the service handle (hService) returned by the open function. This approach allows applications that use interdependent compound devices to be implemented with any combination of single or multiple processes and/or threads, by explicitly managing an appropriate set of application handles. If this facility is not used (indicated by the application using the value WFS_DEFAULT_HAPP for the hApp parameter in WFSOpen), the XFS subsystem automatically treats each process as having a single, unique application handle. See Section 3.5 for additional discussion of this topic.

The lock policy for interdependent compound devices uses the same rules as for independent devices, with some additional constraints. In order to synchronize access via multiple logical services to a single physical device, or to interdependent devices, the service manages a single lock queue and a single deferred queue for the set of related logical services. The additional constraints are:

Service state: LOCK_PENDING

Service state: LOCKED