The EXEC CICS ADDRESS CWA command allows an application to obtain the address of the CWA, which is a piece of storage CICS provides for shared use by any applications. Typically, this is used to act as a “commarea” between different applications. While this sort of shared storage is safe when accessed in a serialized manner, its contents can’t be guaranteed to be consistent when used in a concurrent processing environment.
CICS applications that execute under Open TCBs can potentially be simultaneously referencing (or worse, updating) fields in the CWA, with other applications running under the QR TCB, too. This can lead to data integrity problems in the CWA and unpredictable program results. DFHEISUP can be used to detect the presence of EXEC CICS ADDRESS CWA commands in target application programs being scanned for commands that access shared storage in CICS. These are the EXEC CICS ADDRESS CWA, EXTRACT EXIT, and GETMAIN SHARED commands. The DFHEIDTH filter table is provided for use by
DFHEISUP to detect these. Once detected, you can make the application(s) threadsafe with suitable changes to their logic. For example, you could use ENQ and DEQ operations around the logic that references/updates CWA fields. In cases where this isn’t appropriate, say perhaps due to no longer having access to the original source of the program(s), the CICS RDO PROGRAM definitions may need to be changed to redefine them as quasi-reentrant once more.
A harder problem to identify is when applications acquire their own storage by means other than the EXEC CICS GETMAIN SHARED API. An example could occur if they issue MVS GETMAIN calls to acquire OSCORE storage, rather than EXEC CICS GETMAIN storage from the CICS DSAs. If this storage is shared between applications, there’s the potential for concurrency-related problems in the same manner as those previously described when using the CWA. Since MVS GETMAIN calls are made to acquire such storage, the DFHEIDTH filter table and DFHEISUP can’t detect them. Such sharing of non-CICS managed storage must be identified by a careful analysis of the programs before redefining them as being threadsafe. Again, suitable serialization techniques would be required to ensure that any such shared storage was accessed in a well-defined manner when used in a concurrent Open TCB environment.
TCA and TCB Considerations
Addressing a task’s Task Control Area (TCA) control block used to be possible via the CSACDTA field in the CICS Common System Area (CSA). However, use of this field is reliable only when executing under the QR TCB. With the introduction of OTE, it’s not safe to assume the TCA address held in CSACDTA is the TCA of the task that’s inquiring upon the address. CSACDTA contains the address of the task currently dispatched under the QR TCB. The task that’s looking at this field may be executing under an Open TCB (possibly an L8). The wrong TCA address would be picked up by the program, leading to problems when referencing it.
Use the CICS System Programming Interface (SPI) for programs that wish to access task state information; it provides this information in a threadsafe manner and avoids the problem inherent in using CSACDTA. The CSACDTA field was renamed to CSAQRTCA in CICS Transaction Server 3.1 to discourage any remaining use of this field to access a TCA address.
An application defined as API(OPENAPI) can potentially use non- CICS APIs. Use of such APIs generally requires that the key of the TCB running the program matches the execution key as held in the Program Status Word (PSW). For this reason, CICS provides L9 TCBs for those user key programs defined with API(OPENAPI), and L8 TCBs for those CICS-key programs. This is different from a program defined as API(CICSAPI) since this uses only CICS APIs and applications can successfully run in either CICS-key or user-key, regardless of the key associated with the TCB they’re running under. Such programs can execute under the QR TCB, an L8, or an L9 TCB.
OPENAPI programs are given control under an Open TCB. The program logic must be executed under that TCB. This means there’s potential for additional TCB switching to occur in some circumstances. For example, if a user-key OPENAPI program is given control, it will execute under an L9 TCB. If it invokes a non-threadsafe EXEC CICS command, this will require an automatic switch to the QR TCB for the duration of the command, followed by a switch back to the L9 TCB upon completion of the CICS API call. Similarly, if such a program issues a call to an OPENAPI TRUE such as DB2, this must be executed under an L8 TCB and so automatic switches to and from the L8 TCB must occur while DB2 is being called.
For these reasons, be careful when deciding to define threadsafe user-key applications as API(OPENAPI). Candidates for this would be those programs that issue few, if any, non-threadsafe EXEC CICS commands. Also, you might consider programs that don’t tend to invoke OPENAPI TRUEs. Beyond that, good candidates would be programs that need to perform CPU-intensive workloads or wish to invoke non-CICS APIs.