× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Hi Charles,


You said, "reclaiming TRYAG1" I was thinking that was a typo and you
meant "reclaiming TRGAG2"


It wasn't a typo. I meant TRYAG1.

TRYAG2 has /already/ been reclaimed, as Alan pointed out at the start of this discussion. Reclaiming it again isn't going to do anything, since it's not currently active.

Here's what's happening:

1) TRYAG1 activation group is created.

2) The TRYAG1 program is activated into the TRYAG1 activation group.

3) All variables used by TRYAG1 program will be stored in TRYAG1 actgrp. Because that's what activations are...

4) TRYAG2 activation group is created.

5) The TRYAG2 service program (which includes the tryag2() procedure) is activated into the TRYAG2 activation group.

6) The TRYAG1 program resolves a procedure pointer to the tryag2() procedure. Although the procedure itself is in the TRYAG2 activation group, the procptr is in the TRYAG1 activation group, since the pointer is a variable in the TRYAG1 program.

7) The TRYAG2 program uses the procptr to call tryag2()

8) tryag2() crashes, which takes out the TRYAG2 activation group, and everything in it.

9) TRYAG1 catches the error with MONITOR.

10) TRYAG1 tries to call tryag2() again using the same pointer... however, since the TRYAG2 actgrp is gone, the pointer is invalid, and kaboom.

My point: If you reclaimed the TRYAG1 activation group, this would reset the procptr, and therefore TRYAG1 could once again call tryag2().

So how could you do that? Well, you'd have to add an extra layer, a program that was able to recognize the failure, reclaim the activation group, and restart it. Again, like I said to Mark, this won't work in every situation, and isn't right for every situation, might it might make sense in some.

For example, you might add a TRYAG0 (zero) that calls TRYAG1 repeatedly until TRYAG1 is able to be successful.

Example... well, TRYAG2 wouldn't change, it'd still look like this:

*> CRTRPGMOD TRYAG2 SRCFILE(QRPGLESRC) DBGVIEW(*LIST)
*> CRTSRVPGM TRYAG2 EXPORT(*ALL) ACTGRP(TRYAG2)
H NOMAIN
D TRYAG2 pr
P TRYAG2 b export

D QMHSNDPM PR ExtPgm('QMHSNDPM')
D MessageID 7A Const
D QualMsgF 20A Const
D MsgData 32767A Const options(*varsize)
D MsgDtaLen 10I 0 Const
D MsgType 10A Const
D CallStkEnt 10A Const
D CallStkCnt 10I 0 Const
D MessageKey 4A
D ErrorCode 8192A options(*varsize)

d MsgKey s 4a

d ErrorCode ds
d x 10i 0 inz(0)
d y 10i 0 inz(0)

/free
QMHSNDPM( 'CPF9897'
: 'QCPFMSG *LIBL'
: 'Test'
: 4
: '*ESCAPE'
: '*'
: 0
: MsgKey
: ErrorCode );
/end-free
P e

TRYAG1 would change a little bit, it'd have to keep track of whether TRYAG2 was successful or not... so it'd have to be something like this:

*> CRTRPGMOD TRYAG1 SRCFILE(QRPGLESRC) DBGVIEW(*LIST)
*> CRTPGM TRYAG1 BNDSRVPGM(TRYAG2) ACTGRP(TRYAG1)
D tryag2 pr

D tryag1 pr
D result 10a
D tryag1 pi
D result 10a

/free
result = 'SUCCESS';

monitor;
tryag2();
on-error;
result = 'FAIL';
endmon;

*inlr = *on;
/end-free

And the new program, TRYAG0, would simply call TRYAG1, reclaim it's AG, then call it again, etc, until it was successful:

*> CRTRPGMOD TRYAG0 SRCFILE(QRPGLESRC) DBGVIEW(*LIST)
*> CRTPGM TRYAG0 BNDSRVPGM(TRYAG1) ACTGRP(TRYAG0)
D tryag1 pr extpgm('TRYAG1')
D result 10a

D qcmdexc pr extpgm('QCMDEXC')
D cmd 200a const
D len 15p 5 const

D result s 10a

/free
dou result = 'SUCCESS';
tryag1(result);
qcmdexc('rclactgrp tryag1': 200);
enddo;

*inlr = *on;
/end-free

A few notes, however:

1) Note that my code, above, will make an endless loop. TRYAG0 repeats until TRYAG1 reports success -- which will never happen, as written, since TRYAG2 always crashes :)

2) If TRYAG1 needs to be a *PGM instead of a *SRVPGM... That should be clear from the compile commands above, but it's worth mentioning again, because if you made TRYAG1 into a *SRVPGM, then you'd get the "reference to object that no longer exists" on both layers.

3) I'm _not_ posting this as a recommendation. Merely as a technical, mechanical, possibility that helps folks understand the situation. My actual recommendation would be to add proper error handling into TRYAG2... I tried to say this earlier, but somehow got embroiled into this whole fiasco.


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.