[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP DECwindows Motif
for HP OpenVMS Alpha
New Features


Previous Contents Index

3.1.3 Enabling Support for Multithreading

To enable multithreading, a client application must include initial calls to the multithreading functions in Table 3-2. The specific functions called by the application depend on the shared image(s) in use.

Table 3-2 Multithreading Functions
Function In Image Enables Multithreading For
DECW$LCN_THREAD_INIT DECW$LCNLIBSHR Transport Interface
IceInitThreads DECW$ICELIB ICE and XSMP
XInitThreads DECW$XLIBSHR Xlib and X Extensions
XtToolkitThreadInitialize DECW$XTLIBSHRR5 Xt

Note that IceInitThreads and XInitThreads implicitly call DECW$LCN_THREAD_INIT. The interface to DECW$LCN_THREAD_INIT is described in Section 3.2.

These functions have no arguments and return a success status upon successful initialization. To ensure successful initialization, be sure to:

  • Link the image with threads.
  • Verify there is adequate process memory.
  • Issue the initialization call prior to making any other call.

In addition to calling one of the multithreading functions, a client application must also be linked against the POSIX Threads Library. For example:


$  LINK THREAD_ICO/THREADS SYS$INPUT/OPT
SYS$LIBRARY:DECW$XLIBSHR/SHARE
SYS$LIBRARY:PTHREAD$RTL/SHARE

Explicit links against the threads library are not required if the application calls POSIX thread functions (such as, pthread_create).

3.1.4 Developing Applications with Thread-Aware Images

If a thread-aware image is used in a multithreaded application, the image must not accept concurrent calls nor make calls to other images that could change the state of the thread-aware image.

Note that if a thread-aware application uses the XtAppMainLoop or XtMainLoop function for dispatch handling, calls to the image will be made from callback functions. Xt makes these callbacks with an exclusive lock held on the application context. To avoid conflicts and deadlocks, applications that use a thread-aware image should include calls to XtAppLock before and XtAppUnlock after each call, or sequence of calls, to the image. The application must also call XtProcessLock and XtProcessUnlock to protect the thread-aware image against changes made by Xt to process global data.

In the following example, an application contains a background thread that constantly checks for error situations and displays an error message when a problem occurs. The main program thread first initializes thread support, creates the application context, creates the background thread, and then enters the Xtmain loop:


 static XtAppContext app_context;

int main ()
{
    .
    .
    .
    MrmInitialize ();
    XInitThreads ();
    XtToolkitThreadInitialize();
    XtToolkitInitialize();
    app_context = XtCreateApplicationContext();
    .
    .
    .
    pthread_create (&thread, 0, backgroundCode, 0);
    .
    .
    .
    XtAppMainLoop(app_context)
}

Code for the background thread is as follows:


void* backgroundCode (void* data)
{
   .
   .
   .
   if (problem_detected)
   {
       XtAppLock (app_context);
       XtProcessLock();
       if (! dlog ) dlog = XmcreateWarningDialog (...);
                           XtManageChild(dlog);
                           XSync(display, 0);
                           XtProcessUnlock();
                           XtAppUnlock(app_context);
    }
    .
    .
    .
}

Callbacks for handling the main events of the application do not require changes for multithreading, since they are called with the application context already locked.

Worker Threads

Each of the DECwindows Motif libraries can create worker threads to support multithreading. These threads are identified by their name, which begins with the string DECW$.

Worker threads typically operate at an elevated priority to prevent task inversion, where a high-priority application thread is waiting for the worker thread to complete its operation. Note that worker threads are typically used for short duration tasks, such as responding to an internal AST or sending a status broadcast to all threads waiting for a particular activity.

Upcalls and Kernel Threads

In general, HP DECwindows Motif for HP OpenVMS Alpha Version 1.3 supports client applications either with or without upcalls or multiple kernel threads enabled. However, to avoid problems with priority inversion, HP recommends that upcalls be enabled for all applications that use XtAppAddInput. If upcalls cannot be enabled, then HP recommends assigning the same priority to all threads that use DECwindows Motif.

For example, an application calls XtAppAddInput to request a response to an OpenVMS event flag. The worker thread executes a SYS$WFLOR system call to wait for the event flag. Without upcalls enabled, this thread remains available even though there is no event flag set. And as a result, lower priority threads would not be scheduled.

Cancellation Points

Although some calls in the thread-safe libraries include cancellation points, the action of canceling threads that are executing DECwindows Motif functions is not supported. Canceled threads may hold locks, which can block other threads.

Multiple Application Contexts

Note that multiple application contexts should not be used with multiple threads and thread-aware images. Thread-aware images may contain process global data that requires a single lock to control the data. However, multiple calls to thread-aware images may be made from Xt event handling functions prior to acquiring the lock.

3.2 Support for the Logical Connection Number (LCN) Interface

HP DECwindows Motif for HP OpenVMS Alpha Version 1.3 introduces an interface for determining when an I/O channel is ready and available for use. The logical connection number (LCN) interface is now used to signal when DECwindows Motif I/O channels are available, including those for Inter-Client Exchange (ICE), local and remote X server, and for Input Method Server connections.

Previously, DECwindows Motif used an OpenVMS event flag number (EFN) to signal when input was received from the X server. However, EFNs cannot be used safely in a multithreaded environment. The LCN interface allows multiple threads to handle the same, or different, connections without any thrashing or unnecessary delays.

The following sections further describe the functions of the LCN interface and provide detailed information about the supported routines.

3.2.1 LCN Functions

The principal function of the LCN interface is to test the readiness of an I/O channel. The design of the interface is based on the UNIX select function, which tests the state of UNIX file descriptors and returns when one of them is ready or a timeout occurs.

On OpenVMS, the LCN routines perform the following operations:

  • Initialize support for multithreading
  • Allocate a connection number
  • Query the status of a connection number
  • Signal when input is available

3.2.1.1 Initializing Thread Support

LCN routines can execute in a single-threaded environment using EFNs to signal input or in a multithreaded environment using POSIX Threads routines. Multithreading is enabled with the DECW$LCN_THREAD_INIT routine.

With multithreading enabled, the select routines (DECW$LCN_SELECT_ONE and DECW$LCN_SELECT) can be called concurrently from multiple kernel threads in user mode and one kernel thread in exec mode. Calls from user mode ASTs are not allowed.

With single threading, the select routines can be called from user mode and exec mode ASTs. Note, however, that the only concurrent calls allowed are one call from user mode followed by one call from an AST in user mode.

3.2.1.2 Allocating Connection Numbers

LCNs are allocated to a connection using the DECW$LCN_ALLOCATE routine. Values for LCNs start at 64 to distinguish them from local event flags. The maximum number of concurrently allocated LCNs equals the open file limit of the process. If the quota is 0, a default value of 1023 is used. If the quota exceeds the maximum value, a value of 2047 is used.

Once an LCN is allocated, it is unavailable for reuse until freed by the DECW$LCN_FREE routine.

3.2.1.3 Querying Status and Signaling Input

Each LCN has three status flags, which signify whether an LCN is ready and has received input from a particular operation. Each flag can be either set (1) using the DECW$LCN_SET_x_READY routine or cleared (0) using the DECW$LCN_CLEAR_x_READY routine.

Input is signaled by setting the appropriate ready flag. The following table lists each LCN flag and describes when it is typically set and cleared.

Flag Description
read ready Set when there is data available to read.
write ready Set when there is space in internal buffers to which data can be written.
except ready Set when there is high-priority (exceptional) input.

Each flag can be set individually, and a select operation can test any combination of them. There are two routines that essentially mirror the UNIX select function, and test the ready state of an LCN. DECW$LCN_SELECT selects and tests the status of a range of LCNs or EFNs. DECW$LCN_SELECT_ONE performs the same function, however only tests the status of a single LCN.

3.2.2 LCN Routines

This section describes each of the LCN routines, which are available from the library image DECW$LCNLIBSHR.EXE. To support use from protected images that cannot use the client library, some functions are also available as part of the X Transport system services (DECW$XPORT_SERVICES).

3.2.2.1 DECW$LCN_ALLOCATE

Assigns an LCN.

Format


DECW$LCN_ALLOCATE lcn


Returns


VMS usage:
type: longword (unsigned)
access: write
mechanism: by value

Returns a longword condition value in R0. Condition values returned by this routine are listed under Condition Values Returned.

Arguments

lcn


VMS usage:
type: longword
access: write only
mechanism: by reference

The value of the allocated LCN.

Description

DECW$LCN_ALLOCATE assigns a logical connection number. Initially, each allocated LCN is assigned with all ready flags (read, write, and except) in the clear state (0). The state of these flags can be changed using the DECW$LCN_SET_x_READY routines.

Once allocated, the LCN cannot be reused until it is released by DECW$LCN_FREE. DECW$LCN_ALLOCATE must be called before any query, wait, or signaling operations can be performed.

DECW$LCN_ALLOCATE is both thread- and AST-reentrant and is callable from exec and lower modes.

The equivalent function of DECW$LCN_ALLOCATE is also available as a system service (DECW$XPORT_LCN_ALLOCATE) from the set of transport-common routines (DECW$XPORT_SERVICES.EXE).

Condition Values Returned

SS$_NORMAL Routine successfully completed.
DECW$_INSFMEM There is insufficient memory to perform the operation.
DECW$_NOFREELCN All LCNs are currently allocated.

3.2.2.2 DECW$LCN_CLEAR_x_READY

Changes the ready bit for read, write, or except operations to the clear state.

Format


DECW$LCN_CLEAR_READ_READY lcn [, prior]


DECW$LCN_CLEAR_WRITE_READY lcn [, prior]


DECW$LCN_CLEAR_EXCEPT_READY lcn [, prior]


Returns


VMS usage:
type: longword (unsigned)
access: write
mechanism: by value

Returns a longword condition value in R0. Condition values returned by this routine are listed under Condition Values Returned.

Arguments

lcn


VMS usage:
type: longword
access: read only
mechanism: by value

The value of the LCN whose ready bit for read, write, and except operations will be changed to the clear state (0).

[prior]


VMS usage:
type: longword
access: write only
mechanism: by reference

The previous state of the associated ready flag, either clear (0) or set (1).

Description

DECW$LCN_CLEAR_x_READY clears the read, write, or except ready bit of an LCN. This indicates that the LCN is not available for input from the specified operations.

These routines are thread- and AST-reentrant and callable from exec and lower modes.

The equivalent functions of DECW$LCN_CLEAR_x_READY are also available as system services (DECW$XPORT_LCN_CLEAR_x) from the set of transport-common routines (DECW$XPORT_SERVICES.EXE). Note that when using the system service, the prior argument is required; use a 0 value to prevent the prior state from being returned.

Condition Values Returned

SS$_NORMAL Routine successfully completed.
DECW$_NOT_INITIALIZED The LCN has not been initialized; DECW$LCN_ALLOCATE must be called prior to this operation.
DECW$_INVLCN The LCN has not been allocated.

3.2.2.3 DECW$LCN_FREE

Deassigns an allocated LCN.

Format


DECW$LCN_FREE lcn


Returns


VMS usage:
type: longword (unsigned)
access: write
mechanism: by value

Returns a longword condition value in R0. Condition values returned by this routine are listed under Condition Values Returned.

Arguments

lcn


VMS usage:
type: longword
access: read only
mechanism: by value

The value of the LCN to be freed.

Description

DECW$LCN_FREE deassigns the specified LCN. Once freed, the LCN is available for immediate reallocation.

This routine is thread- and AST-reentrant and callable from exec and lower modes.

The equivalent function of DECW$LCN_FREE is also available as a system service (DECW$XPORT_LCN_FREE) from the set of transport-common routines (DECW$XPORT_SERVICES.EXE).

Note

If either DECW$LCN_SELECT_ONE or DECW$LCN_SELECT has been called to test a state of the LCN which has been freed, then the status DECW$_INVLCN is returned from the select call.

Condition Values Returned

SS$_NORMAL Routine successfully completed.
SS$_INSFMEM There is insufficient memory to perform the operation.
DECW$_NOT_INITIALIZED The LCN has not been initialized; DECW$LCN_ALLOCATE must be called prior to this operation.
DECW$_INVLCN The LCN has not been allocated or is protected.

3.2.2.4 DECW$LCN_SELECT

Tests the ready state(s) of one or more LCNs and returns when one of the tested states is set, a timeout occurs, or a specified OpenVMS event flag is set.

Format


DECW$LCN_SELECT retcount, rmask, wmask, emask, [timeout], [efn], [efn_mask]


Returns


VMS usage:
type: longword (unsigned)
access: write
mechanism: by value

Returns a longword condition value in R0. Condition values returned by this routine are listed under Condition Values Returned.

Arguments

retcount


VMS usage:
type: longword
access: write only
mechanism: by reference

The total number of entries set in the three mask structures (rmask, wmask, emask).

rmask, wmask, emask


VMS usage:
type: mask
access: read,write
mechanism: by reference

Specifies whether to check the read (rmask), write (wmask), or exception (emask) status of one or more LCNs. A value indicates that the status check be performed; a null value indicates that no check be made. On completion, the mask is updated to reflect which LCNs have their ready state set.

The format of each mask is an array of word values. The first entry is the number of remaining entries in the array. Each subsequent entry represents an LCN value.

timeout


VMS usage:
type: quadword
access: read only
mechanism: by reference

The time by which the select operation will timeout if no input is received. The time value is expressed in OpenVMS binary delta-time format. A null value indicates no timeout. A value of 0 indicates the operation is in polling mode and will timeout immediately if none of the specified status bits are set.

efn


VMS usage:
type: longword
access: read only
mechanism: by value

An event flag number (EFN) in the cluster to which the efn_mask argument applies. EFNs are typically used for single-threaded or inner-mode operations. In this environment, efn identifies an event flag for the wait operation.

If no EFN value is provided in single-thread mode, SYS$HIBER and SYS$WAKE are used. In these instances, SYS$HIBER must not be used concurrently within the process. In particular, POSIX Threads must not be loaded into the image, even if not in use.

For multithreaded, user mode operations, this argument can be optional depending on whether an EFN has been provided previously to DECW$LCN_THREAD_INIT. If the EFN was specified and the value of efn_mask is 0, the argument is optional. Otherwise the value of this argument is required and will be used as if it had been provided to DECW$LCN_THREAD_INIT.

efn_mask


VMS usage:
type: longword
access: read only
mechanism: by value

A mask of EFNs to be tested. Requires the efn argument.

Description

DECW$LCN_SELECT waits until one of the specified LCN ready states has been set, timed out, or until the event flag condition is met. This routine checks whether the selected LCNs have been allocated and returns an error (DECW$_INVLCN) if one or more LCNs have either not been allocated or freed for reuse.

With multithreading enabled, this routine is thread-reentrant and callable from exec or lower modes. Calls from ASTs are not supported.

With single threading, the select routines can be called from user mode and exec mode ASTs. Note, however, that the only concurrent calls allowed are one call from user mode followed by one call from an AST in user mode.

Condition Values Returned

SS$_NORMAL Routine successfully completed. One or more LCNs have their ready bit set as indicated in the updated mask values.
SS$_EXQUOTA A process quota has been exceeded, this can be due to the timer entry or AST limit quota.
SS$_INSFMEM There is insufficient memory to perform the operation.
SS$_UNASEFC The process is not associated with the cluster that contains the specified event flag.
DECW$_BAD_EFN_CLUSTER An event flag was not provided to DECW$LCN_THREAD_INIT, or the specified flag resides in a different event flag cluster.
DECW$_EFN_SET One or more event flags in the mask have been set.
DECW$_INVARG The array count in a read, write, or exception mask, or the timeout value is not valid.
DECW$_INVLCN One or more LCNs have not been allocated or were freed during the operation.
DECW$_NOHIBER This call was made from inner-mode with multithreading enabled. No EFN was specified.
DECW$_PTHREAD_INVALID A POSIX Threads routine returned an unexpected error.
DECW$_TIMEDOUT The end of the timeout period was reached.


Previous Next Contents Index