Well, in this case, it is actually working as designed. The use of WeakReferences allows a package file to be kept in the global cache, while at the same time not creating a memory leak. As long as there are some references to the package around to keep things alive, the weak reference will never get cleared and the package is not garbage collected. Once all users of the package go away, the weak reference can be cleared and the package memory reclaimed. If that happens, then the package will get reloaded on the next usage.
Rick On Wed, Mar 25, 2009 at 12:04 PM, Mark Miesfeld <miesf...@gmail.com> wrote: > Rick, > > When you have time can you take a look at this. It is another case > where I see why the problem is happening but don't know what a good > fix is. > > I added a subdirectory to the incubator at: > > oorexx/incubator/4.0.0.examples/api/reader.writer/no.prologue > > that has the code to create a program that demonstrates this problem: > > When RexxStart() is used to call the interpreter several times in the > same process to run a Rexx program that has a ::requires, and the > required file has a prologue of executable code, the prologue only > executes for the first use of RexxStart(). On the successive > RexxStart()s the prologue does not execute. But, it only happens for > some ::requires files. > > There is a make file to build the executable, you'll just need to edit > the line towards the top to point to your build directory. After you > build run rxStart.exe with no args to see an example of when the > prologue does execute for each RexxStart(). Run rxStart with the arg > of logon.rex to see an example of when the prologue only executes for > the first RexxStart(). You'll get output similar to: > > E:\work.ooRexx\other\examples\4.0.examples\no.prologue>rxstart > C++, round # [1] ... > req02.rex: in prolog code of [req02.rex] > Hello World from prolog code of req02.rex > req01.rex: in prolog code of [req01.rex] > Hello World from prolog code of req01.rex > simple.rex: in [simple.rex], received arg: [1] > ... RexxStart() return code=[0] | returned result value=[returning > from ooRexx: <1>] | converted return code=[0] > --- > C++, round # [2] ... > req02.rex: in prolog code of [req02.rex] > Hello World from prolog code of req02.rex > req01.rex: in prolog code of [req01.rex] > Hello World from prolog code of req01.rex > simple.rex: in [simple.rex], received arg: [2] > ... RexxStart() return code=[0] | returned result value=[returning > from ooRexx: <2>] | converted return code=[0] > --- > C++, round # [3] ... > req02.rex: in prolog code of [req02.rex] > Hello World from prolog code of req02.rex > req01.rex: in prolog code of [req01.rex] > Hello World from prolog code of req01.rex > simple.rex: in [simple.rex], received arg: [3] > ... RexxStart() return code=[0] | returned result value=[returning > from ooRexx: <3>] | converted return code=[0] > --- > > E:\work.ooRexx\other\examples\4.0.examples\no.prologue>rxstart logon > C++, round # [1] ... > In oodPlain.cls > XXXXXXX-Make sure this marker is seen-XXXXXXXXXXXXXXXXXXXXX > The user is granted access to the system. > ... RexxStart() return code=[1] | returned result value=[1] | > converted return code=[1] > --- > C++, round # [2] ... > The user is granted access to the system. > ... RexxStart() return code=[2] | returned result value=[2] | > converted return code=[2] > --- > C++, round # [3] ... > The user is granted access to the system. > ... RexxStart() return code=[3] | returned result value=[3] | > converted return code=[3] > --- > > E:\work.ooRexx\other\examples\4.0.examples\no.prologue> > > What happens is, in PackageManager::loadRequires(), for the first > RexxStart(), the checkRequiresCache() for the resolvedName returns > OREF_NULL, and then getRequiresFile() is called and the prologue gets > executed for both cases. > > For the second RexxStart(). > > For the case where the prologue is executed: in checkRequiresCache() > for this code: > > WeakReference *requiresRef = (WeakReference *)loadedRequires->get(name); > if (requiresRef != OREF_NULL) > { > PackageClass *resolved = (PackageClass *)requiresRef->get(); > if (resolved != OREF_NULL) > { > result = resolved; > return resolved; > } > // this was garbage collected, remove it from the table > loadedRequires->remove(name); > } > > The weak reference requiresRef is not null, but the resolved > PackageClass is null, so OREF_NULL is returned, getRequiresFile() is > invoked and the prologue executes. > > For the case where the prologue is not executed, requiresRef is not > null and resolved is not null, so resolved is returned and > getRequiresFile() is skipped. With getRequiresFile() skipped, the > prologue is never executed. > > -- > Mark Miesfeld > > ------------------------------------------------------------------------------ > _______________________________________________ > Oorexx-devel mailing list > Oorexx-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/oorexx-devel > ------------------------------------------------------------------------------ _______________________________________________ Oorexx-devel mailing list Oorexx-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/oorexx-devel