Skip to content

Commit 387e9c7

Browse files
authored
Merge pull request #181 from evolvedbinary/6.x.x/hotfix/util-eval-memory-leak
[6.x.x] Fix a memory leak in the util:eval XPath functions
2 parents ac8036d + e26f7a0 commit 387e9c7

3 files changed

Lines changed: 29 additions & 13 deletions

File tree

exist-core/src/main/java/org/exist/xquery/Context.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ public interface Context {
9898

9999
XQueryContext getRootContext();
100100

101+
/**
102+
* Create a new context ("Inner Context") that will share some state with this context.
103+
* After calling this {@link #setShared(boolean)} should be set to true.
104+
*
105+
* @return an inner context.
106+
*/
101107
XQueryContext copyContext();
102108

103109
/**
@@ -334,6 +340,13 @@ public interface Context {
334340

335341
void addLockedDocument(DocumentImpl doc);
336342

343+
/**
344+
* When set as true, it indicates that this Context (often known as the Inner Context)
345+
* shares some state with another Context (often known as the Outer Context).
346+
* This should be set to true after any call to {@link #copyContext()}.
347+
*
348+
* @param shared set to true if this context shares state with another context, false otherwise.
349+
*/
337350
void setShared(boolean shared);
338351

339352
boolean isShared();

exist-core/src/main/java/org/exist/xquery/XQueryContext.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,15 +1554,17 @@ public void reset(final boolean keepGlobals) {
15541554
watchdog.reset();
15551555
}
15561556

1557-
/*
1558-
NOTE: we use `modules` (and not `allModules`) here so as to only reset
1559-
the modules of this module.
1560-
The inner call to `module.reset` will be called on sub-modules
1561-
which in-turn will reset their modules, and so on.
1562-
*/
1563-
for (final Module[] modules : modules.values()) {
1564-
for (final Module module : modules) {
1565-
module.reset(this, keepGlobals);
1557+
if (!isShared) {
1558+
/*
1559+
NOTE: we use `modules` (and not `allModules`) here so as to only reset
1560+
the modules of this module.
1561+
The inner call to `module.reset` will be called on sub-modules
1562+
which in-turn will reset their modules, and so on.
1563+
*/
1564+
for (final Module[] modules : modules.values()) {
1565+
for (final Module module : modules) {
1566+
module.reset(this, keepGlobals);
1567+
}
15661568
}
15671569
}
15681570

@@ -1576,7 +1578,9 @@ public void reset(final boolean keepGlobals) {
15761578

15771579
clearUpdateListeners();
15781580

1579-
profiler.reset();
1581+
if (!isShared) {
1582+
profiler.reset();
1583+
}
15801584

15811585
if (!keepGlobals) {
15821586
httpContext = null;

exist-core/src/main/java/org/exist/xquery/functions/util/Eval.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ private Sequence execute(final DBBroker broker, final XQuery xqueryService, fina
469469
compiled.getContext().prepareForReuse();
470470
}
471471

472-
Sequence sequence = xqueryService.execute(broker, compiled, exprContext, outputProperties, false);
472+
Sequence sequence = xqueryService.execute(broker, compiled, exprContext, outputProperties, true);
473473
ValueSequence newSeq = new ValueSequence();
474474
newSeq.keepUnOrdered(unordered);
475475
boolean hasSupplements = false;
@@ -496,10 +496,9 @@ private Sequence execute(final DBBroker broker, final XQuery xqueryService, fina
496496
if (compiled.getContext() != null) {
497497
compiled.getContext().runCleanupTasks();
498498
}
499+
499500
if (cache) {
500501
pool.returnCompiledXQuery(querySource, compiled);
501-
} else {
502-
compiled.reset();
503502
}
504503
}
505504
}

0 commit comments

Comments
 (0)