Language Environment Pre-Initialization Services are used to create a reusable runtime environment (RRE), run multiple run-time environments in one multi-tasking region, etc. CEEPIPI is the Language Environment version of the previous language-specific RREs, such as IGZERRE in COBOL.
Without CEEPIPI, the LE runtime is created and terminated when the main LE-compatible program starts and ends. For example, if a (non-LE) assembler program driver repeatedly calls a COBOL program, the LE runtime would be started up and torn down upon each call, with adverse performance consequences.
So, in effect, CEEPIPI is doing the same work as would be done when the first LE-program is called. For the rest of this RFE, we will use COBOL to designate a LE-compatible program.
One use case for CEEPIPI is in an IMS/TM online environment. Without CEEPIPI or other mitigation, IMS (which is non-LE assembler) repeatedly calls COBOL transactions, with severe performance degradation. CEEPIPI can be used to keep the runtime system up. (There are consequences to using CEEPIPI in this way. One is that the transaction load module directly called by IMS can not contain any COBOL code. Another is that all COBOL programs in the transaction will remain in memory for the duration of the message region.)
In this scenario, IMS is calling the application transaction via the LINK SVC. And that creates a problem, which would also occur in any other situation where a driver program is LINKing at a higher level than the CEEPIPI environment.
When the RRE is created, LE sets up ESTAE/ESPIE for condition handling. (We'll just refer to this as the LE ESTAE). This ESTAE is tied to the Request Block (RB) that was created by the LINK. When the LINKed program ends, that RB ends, and so does the ESTAEs. Thus, the condition handling set up by LE does not survive to a second LINK.
(This isn't an issue when CEEPIPI is NOT used, because each invocation of the top level COBOL program creates a new LE run-time environment, which (re)establishes the ESTAE.)
One example of how this can be an issue is COBOL handling of overflows. Per COBOL semantics, overflows are ignored unless an ON SIZE ERROR is coded. The overflows should not abend. C, on the other hand, is supposed to abend.
COBOL has two methods for achieving this:
1. The run-unit initially has the bit set in the PSW to mask overflow program checks.
2. Even if that bit is set to not mask overflows, LE's ESTAE will catch the overflow and ignore it.
But, what if something turns off the PSW mask bit, and LE's ESTAE is lost? For example, if a COBOL program contains (just contains!) an XML GENERATE or XML PARSE verb, then COBOL will turn off the masking bit, because the XML processing is done in C, which needs to abend for overflows. COBOL assumes that LE's ESTAE will be there to handle any subsequent overflows, so COBOL doesn't bother to reset the bit. So, if the ESTAE is lost, then the overflow will abend in COBOL, even though it shouldn't.
This gives one scenario for a problem. (This is simplified; in reality there are more steps to maintain addressability to tokens):
1. IMS or something uses the LINK SVC to an assembler program
2. The assembler program initializes the CEEPIPI RRE.
3. The assembler program uses CEEPIPI to call a COBOL subprogram.
4. This COBOL program, or some called subprogram, contains an XML verb. The overflow masking bit is now off.
5. The COBOL and assembler programs all end, i.e. the LINKed program ends. This ends the LE ESTAE.
6. IMS or something uses the LINK SVC again to the assembler program.
7. The assembler program uses CEEPIPI to call a COBOL program in the same RRE that was previously established. The LE ESTAE is not restored.
8. This COBOL program, or some called subprogram, does something (such as an overflow) that should be caught and handled by LE's ESTAE
9. But there is no ESTAE, so the program check isn't handled, so it abends.
This RFE is to address the problem: if LE's standard condition handling ESTAE/ESPIEs are lost in a CEEPIPI RRE, such as due to a LINK SVC in the calling chain to the CEEPIPI-established RRE, there is no way to restore it, save for terminated and reinitializing the RRE – which would defeat the purpose of the RRE.
The RFE idea is, therefore, that there should be a way to restore the ESTAE/ESPIEs, such as…
A new CEEPIPI service function that will reestablish the RRE environment, specifically the ESTAE/ESPIEs. This would be less than what is performed by the init_sub function, i.e. there is an existing RRE but it just needs some fixing up.