RPG Exit Strategy
LR & Return, CEE or exit function?
With the advent of ILE, setting on LR, followed by a RETRUN operation might not be enough to allow the system to recover all of the resources assigned to the job. This can be particularly troublesome. Executing in the default activation group, the Original Program Model (OPM) expects that everything is shutdown and the system may reclaim job resources. However, with an Integrated Language Model (ILE) application, LR and RETURN does not release all resources for clean up. If a mix of ILE and OPM programs co-exist, different exit strategies are required.
ctl-Opt DEBUG(*YES) OPTION(*SRCSTMT : *NODEBUGIO) DFTACTGRP(*NO) ACTGRP('QILE') Main(SC0320RP) BNDDIR('QC2LE':'SC0000_BD') ; ******************************************************************** * Program Name - SC0320RP * * * * Function - This program was designed to allow a user to * * work with expansion project objects * * * * Programmer - Steve Croy * ******************************************************************** ******************************************************************** * Compile instructions * *CRTPGM *RPGLE * *DBGVIEW *SOURCE * * * ******************************************************************** ******************************************************************** * Modification log * * * * Date Programmer Description * * * ******************************************************************** **------------ File section ----------------------------------------- Dcl-F SC0320DF WORKSTN UsrOpn SFILE(SC0320S1:RRNSI) INFDS(DSPDS) ; **------------ Data Structures -------------------------------------- /copy qrpglesrc,SCMAPS_pr Dcl-DS functionkey extname('SCKEYSPF') qualified end-DS; Dcl-DS OBJECT extname('SCOBJSPF') end-DS; Dcl-DS before extname('SCOBJSPF') qualified end-DS; Dcl-DS after extname('SCOBJSPF') qualified end-DS; * Default cursor position Dcl-DS #DFPOS INZ ; #DFROW packed(2:0) INZ(8) ; #DFCOL packed(3:0) INZ(17); End-DS ; * Default message file Dcl-DS dftPgmMsgF ; dftMsglib char(10) INZ('*LIBL') ; dftMsgFile Char(10) INZ('SCMSSGF'); End-DS ; **------------ Procedure Prototypes --------------------------------- /copy qrpglesrc,SC0000_pr /copy qrpglesrc,SC0320_pr **------------ Define constants ------------------------------------- Dcl-C #TITLE CONST('** Work With Objects List **') ; **------------ Define Global Variables ------------------------------ Dcl-S dtaPtr pointer inz( %addr(object)); Dcl-S indPtr pointer inz( %addr(*in) ) ; Dcl-DS indicators len(99) based( indPtr ) ; ScreenChange ind pos(22) ; SflControl ind pos(50) ; SflDisplay ind pos(51) ; SflInitialize ind pos(52) ; SflClear ind pos(53) ; SflEnd ind pos(54) ; SflDelete ind Pos(55) ; SflNxtChange ind pos(58) ; SflMSGQdisplay ind pos(59) ; End-DS ; Dcl-S ErrorOccurred ind ; Dcl-S listAction ind ; Dcl-S MessageToDisplay ind ; Dcl-S MoreRecordsRemain ind ; Dcl-S NoMoreRecords ind ; Dcl-S objectFound ind ; Dcl-S authl char(3) inz('999') ; Dcl-S CMDKEY char(720) ; Dcl-S dspatr char(1) ; Dcl-S FKEYDS char(1) ; Dcl-S fmt char(10) inz('BEGIN'); Dcl-S INDLR char(1) ; Dcl-S Keyidx char(2) ; Dcl-S MorOpt char(1) ; Dcl-S MSG char(80) ; Dcl-S MSGDTA char(132) ; Dcl-S MSGF char(10) ; Dcl-S MSGPGM char(10) ; Dcl-S MSGRLQ char(5) ; Dcl-S optIdx char(2) ; Dcl-S OPTION char(720) ; Dcl-S p$err char(7) ; Dcl-S p$mod char(1) ; Dcl-S p$mode char(1) ; Dcl-S parm01 char(10) ; Dcl-S parm02 char(10) ; Dcl-S passc char(1) ; Dcl-S promptDta char(256) ; Dcl-S orderBy char(256) ; Dcl-S selectOnly char(256) ; Dcl-S thisOption char(10) ; Dcl-S thisFormat char(10) ; Dcl-S thisPgm char(10) inz('SC0320RP'); Dcl-S typatr char(1) ; Dcl-S UsrNam char(10) ; Dcl-S CATEG zoned(3:0) inz(500) ; Dcl-S CL zoned(3:0) ; Dcl-S dtaSize int(10) inz( %size(object)); Dcl-S M zoned(3:0) ; Dcl-S O zoned(3:0) ; Dcl-S RCDNBR int(5) INZ(1) ; Dcl-S RRNSI binDec(4) ; Dcl-S RW zoned(3:0) ; Dcl-S SAVRRN binDec(4) ; Dcl-S SFLLOD binDec(4) ; Dcl-S SFLMAX binDec(4) INZ(12) ; Dcl-S SFLPOS binDec(4) ; Dcl-S SFLRCN binDec(4) ; **------------ End of work fields ----------------------------------- Dcl-Proc SC0320RP ; Dcl-PI SC0320RP extPgm('SC0320RP') ; END-PI; CheckAuthority(USER:THISPGM:CATEG:PASSC:AUTHL); IF PASSC <> 'P'; QUIT(); ENDIF; If not %open(SC0320DF); OPEN SC0320DF ; ENDIF; z$seq1 = #TITLE; functionKey = FunctionKeys(); getMessage('MIS0001'); FilterSelect ( zfcat: zfseq: zfobj: zftyp: zfdsc: zfsts: 'GET'); resetDisplay(); DOU keyPressed = functionKey.F3; IF MessageToDisplay; SflMSGQdisplay = *ON; ELSE; SflMSGQdisplay = *OFF; ENDIF; WRITE SC0320C2 ; // write subfile message queue IF ScreenChange; #ROW = #DFROW; #COL = #DFCOL; ENDIF; rrnsi = 0 ; sflControl = *ON ; // Set subfile control on IF sflrcn > 0 ; // and if records were loaded sflDisplay = *ON ; // turn on subfile display ENDIF ; WRITE SC032001; EXFMT SC0320C1; sflControl = *OFF; sflDisplay = *OFF; getCsrLoc(ROW:COL:rw:cl); #ROW = rw; #COL = cl; IF MessageToDisplay; RmvMessage(prgnam); MessageToDisplay = *OFF; ENDIF; ThisFormat = fmtnam; GetFunction(thisPgm:thisFormat:keypressed:fkeyid:macro:authl); SELECT; WHEN KeyPressed = functionKey.ENTER; processChanges(); READ SC032001; If ScreenChange ; resetDisplay() ; ENDIF; WHEN KeyPressed = functionKey.ROLLUP; loadSubfile(); WHEN KeyPressed = functionKey.ROLLDN; pageDown(); WHEN KeyPressed = functionKey.F23; DisplayOptions(option: z$opt1: z$opt2: O); WHEN KeyPressed = functionKey.F24; DisplayKeys(cmdkey: z$key1: z$key2: M); WHEN Function = 'EXIT'; QUIT(); [1] WHEN Function = 'CANCEL'; EXSR returnToCaller; [2] WHEN Function = 'RESET'; resetDisplay(); WHEN Function = 'PROMPT'; READ SC032001; displayPrompt(rtnFld) ; resetDisplay(); WHEN Function = 'HELP'; HelpText(ThisPgm:fmt); WHEN SUBOP = 'CALL'; callProgram(); WHEN Function = 'CMDLINE'; CommandLine(); ENDSL; CLEAR macro; ENDDO; //*---------------------------------------------------------------- BEGSR returnToCaller; If %open(SC0320DF) ; CLOSE SC0320DF ; ENDIF ; ErrorOccurred = CloseObjectCursor() ; *inlr = *on ; return ; ENDSR; End-Proc SC0320RP ; //*================================================================ Dcl-Proc resetDisplay; Dcl-PI resetDisplay end-PI; rrnsi = 1; rcdnbr = 1; sflrcn = 0; sflpos = 0; SflInitialize = *ON; WRITE SC0320C1; SflInitialize = *OFF; SflEnd = *OFF; ThisFormat = fmtnam; m = 0; o = 0; usrnam = user; reset dftPgmMsgF ; GetKeyText(thisPgm:thisFormat:cmdkey:authl); GetOptText(thisPgm:thisFormat: option: authl); DisplayKeys(cmdkey: z$key1: z$key2: M); DisplayOptions(option: z$opt1: z$opt2: O); // Format the SQL request ... FormatSQL ( zfcat: zfseq: zfobj: zftyp: zfdsc: zfsts: SelectOnly: orderBy); CloseObjectCursor(); ClearObject(); SetObjectCursor(orderby: selectOnly); FilterSelect ( zfcat: zfseq: zfobj: zftyp: zfdsc: zfsts: 'SET'); loadSubfile() ; Return ; END-Proc resetDisplay ; //*================================================================ Dcl-Proc pageDown; Dcl-PI pageDown end-PI; Z$RRN2 = Z$rrn2 - SFLMAX; SFLPOS = (SFLPOS - SFLMAX); IF SFLPOS < 1; SFLPOS = sflmax; ENDIF; IF Z$RRN2 < 1; Z$RRN2 = 1; getMessage('MIS0006'); ENDIF; Return ; END-Proc pageDown ; //*================================================================ Dcl-Proc loadSubfile; Dcl-PI loadSubfile end-PI; sfllod = 0; savrrn = z$rrn2; SflEnd = *OFF; NoMoreRecords = *OFF; DOU NoMoreRecords or sfllod >= sflmax; MoreRecordsRemain = NextObject(); IF MoreRecordsRemain; OBJECT = GetObjectData(); sflrcn = sflrcn + 1; sfllod = sfllod + 1; RRNSI = SFLRCN; Z$RRN1 =SFLRCN; z$opt = *BLANKS; z$desc = exdesc; zfstat = *blanks; SELECT; WHEN exproc = 'Y'; dspatr = SetColor('BLU'); typatr = SetColor('WHT'); zfstat = dspatr + 'Revised'; WHEN exproc = 'E'; dspatr = SetColor('YLW'); typatr = SetColor('WHT'); zfstat = dspatr + 'Review'; WHEN exproc = 'X'; dspatr = SetColor('GRN'); typatr = SetColor('GRN'); zfstat = dspatr + 'Tested'; WHEN exproc = 'N'; dspatr = SetColor('GRN'); typatr = SetColor('GRN'); zfstat = dspatr + 'Pending'; WHEN exproc = 'O'; dspatr = SetColor('RED'); typatr = SetColor('RED'); zfstat = dspatr + 'Obsolete'; OTHER; dspatr = SetColor('GRN'); typatr = SetColor('GRN'); zfstat = dspatr + 'Undefined'; ENDSL; zfobnm = dspatr + exobnm + typatr + exobtp; WRITE SC0320S1; ELSE ; Sflend = *ON; NoMoreRecords = *ON; ENDIF; ENDDO; sflpos = sflpos + sflmax; z$rrn2 = (sflpos - sflmax) + 1; IF z$rrn2 > sflrcn; sflpos = sflpos - sflmax; z$rrn2 = savrrn; getMessage('MIS0007'); ENDIF; Return ; END-Proc loadSubfile ; //*================================================================ Dcl-Proc callProgram; Dcl-PI callProgram end-PI; setParameters(); MONITOR; CallPrograms( subPgm : callPM : subAct : dtaPtr : dtaSize: p$err ) ; ON-ERROR; P$ERR = 'MIS0012'; GetMessage('MIS0012'); ENDMON; getParameters(); Return ; END-Proc callProgram ; //*================================================================ Dcl-Proc setParameters; Dcl-PI setParameters end-PI; p$err = *blanks; IF listAction; IF RetrieveObject(exobnm:exobtp); before = GetObjectData(); ELSE; CLEAR before; ENDIF; ENDIF; Return ; END-Proc setParameters ; //*================================================================ Dcl-Proc getParameters; Dcl-PI getParameters end-PI; IF listAction; IF RetrieveObject(exobnm:exobtp); after = GetObjectData(); ELSE; CLEAR after; ENDIF; ENDIF; IF p$err <> *BLANKS; getMessage(P$ERR); ENDIF; Return ; END-proc getParameters ; //*===================================================================== Dcl-Proc getMessage ; Dcl-PI getMessage ; thisMsg char(7) const ; end-PI ; msgID = thisMsg ; msgdta = *BLANKS; msg = *BLANKS; msgf = dftMsgFile; MONITOR; RtvMessage(msgid:msgf:msgdta:msg); msgtxt = msg; ON-ERROR; msgf = errFil; ENDMON; msgRlq = '*SAME' ; msgdta = msgtxt; msgpgm = PRGNAM; SndMessage(msgid : msgF: msgdta : msgrlq : msgpgm); MessageToDisplay = *ON; Return ; END-Proc getMessage ; //*===================================================================== Dcl-Proc Quit ; Dcl-PI *n end-PI ; ErrorOccurred = CloseObjectCursor(); *inlr = *on ; exit(0) ; Return ; End-Proc Quit ; //*===================================================================== Dcl-Proc displayPrompt ; Dcl-PI displayPrompt ; promptField char(10) ; END-PI; Dcl-S pmt char(10) ; If promptField = *blanks; pmt = 'PROMPT' ; Else ; pmt = promptField ; ENDIF; PromptDta = *blanks; Prompter( Thispgm : pmt : PromptDta ); SELECT; WHEN rtnfld = 'ZFSTS'; zfsts = %trim(PromptDta); WHEN rtnfld = 'ZFSEQ'; promptDta = %xlate(' ':'0':promptDta); zfseq = %dec(%subst(PromptDta:1:7):7:0); WHEN rtnfld = 'ZFCAT'; promptDta = %xlate(' ':'0':promptDta); zfcat = %dec(%subst(PromptDta:1:3):3:0); WHEN rtnfld = 'ZFOBJ'; zfobj = %trim(PromptDta); WHEN rtnfld = 'ZFTYP'; zftyp = %trim(PromptDta); WHEN rtnfld = 'ZFDSC'; zfdsc = %trim(PromptDta); OTHER; PromptDta = *blanks; ENDSL; Return ; END-Proc displayPrompt ; //*===================================================================== Dcl-Proc processChanges; Dcl-PI processChanges end-PI; IF Z$RRN1 > 0; DOU %eof(SC0320DF); READC SC0320S1; listAction = *off; IF NOT %eof(SC0320DF); IF Z$OPT <> *BLANK; listAction = *ON; thisOption = %triml(z$opt); ThisFormat = fmtnam; GetOption(Thispgm:ThisFormat:thisOption:macro:authl); SELECT; WHEN SUBOP = 'CALL'; callProgram(); Other ; setParameters() ; executeFunction( exobnm : exobtp : function : p$err); getParameters() ; ENDSL; z$opt = *BLANK; IF before <> after; SELECT; WHEN p$mode = 'C'; OBJECT = after; exdesc= '*changed'; WHEN p$mode = 'D'; exdesc = '*deleted'; *IN30 = *ON; ENDSL; ENDIF; z$rrn2 = z$rrn1; UPDATE SC0320S1; *IN30 = *OFF; CLEAR MACRO; ENDIF; ENDIF; ENDDO; ENDIF; Return ; END-PROC processChanges ; ;