On 3/3/2011 1:02 PM, Lluis Maldonado wrote:
could someone explain me why Using *caller with dftactgrp causes big problems.
I wouldn't say big problems, only that I don't recommend it among the
alternatives.
We can think of two runtime environments on the i: OPM and ILE. OPM
seems easy enough, it's what we're all used to. CL and RPG III run in OPM.
ILE is a little harder because a fundamental idea in ILE is program
activation which means activation groups. IBM gave us 4 kinds of AGs:
dftactgrp(*yes), *NEW, named and *CALLER.
dftactgrp(*yes) is an OPM compatibility mode. It lets us convert our
RPG III syntax programs to RPG IV and will run it as if it were OPM.
That's pretty neat because we get to use long variable names, big arrays
and all that. But if we want to use a sub-procedure, we must leave OPM
compatibility mode for true ILE mode. For the sake of convenience we
call this the default activation group (DAG). An override touches all
programs, storage is freed and files closed when each program ends
(depending on LR). Every program shares with all the rest in that job.
*NEW activates your program into a brand new AG. Every time your
program is called, a new AG is created and your program activated in it.
When your program ends, the AG is destroyed. Files closed, storage
freed. This is easy, but it sets up an environment where every program
is isolated from every other program in that job.
Named AGs are very similar to *NEW, except that you, not the system,
decide when to create and destroy them. They are not defined at run
time, but at compile time. One way to think of them is that you want
your accounts payable programs to all run in the same AG, to share
overrides and maybe open data paths. When you do OVRDBF(VENDOR)
TOFILE(TESTLIB/VENDOR) only the A/P programs will see that; programs
running in ACTGRP(GENERALLEDGER) will not. Activation groups let you
group together similar programs and isolate them from dissimilar programs.
Let's say that one of the programs the A/P clerks use all the time is a
vendor search. Let's also say that it gets used by other applications
like General Ledger. If you put VENDSEARCH in actgrp(AP), and the user
calls it from anywhere - even from the G/L menu, he will see the
overrides from actgrp(AP). You probably don't want this. Instead, you
want VENDSEARCH to have the overrides from actgrp(GL) *CALLER is how
you do that. *CALLER lets you write a program that inherits the AG of
the caller. This works great when you want to call the same program
from multiple menus in the same job.
When *CALLER is used and the top menu is an OPM program, we have told
the system to run an ILE program in OPM compatibility mode. It will
activate in the DAG OK, storage will initialise, files open, code will
run. When LR comes on though, strange things happen. The program comes
off the call stack but storage is not freed. RPG closes the files and
the program seems to have finished. But when you call it again, it is
already activated, and does not go through the full activation process
again. In particular, it doesn't reinitialise the internal static
storage, which usually is not a problem for a *PGM object.
*SRVPGM objects have a different termination mechanism - which is to say
that they don't. They're intended to stay active for the life of the
AG. When they run in OPM compatibility mode and someone does a RCLRSC,
the open files are closed but the *SRVPGM does not know that. The next
time a sub-procedure is called in from that service program, you'll get
a MCH3402.
For an overview of recommendations on things to avoid, see 'Seven Deadly
Sins of ILE'
http://www.ibmsystemsmag.com/ibmi/developer/7923p1.aspx
The RPG Programmer's Manual has a section about termination in Chapter
10; Returning from a Called Program or Procedure. The ILE Concepts
Manual has a section on program activation in Chapter 3; ILE Advanced
Concepts.
I hope that helped some.
--buck
As an Amazon Associate we earn from qualifying purchases.