Permalink
Browse files

Merge pull request #283 from opax/deadlock-fix

[bugfix] remove possible deadlock in XQueryPool
  • Loading branch information...
2 parents 2580e90 + 01b09ce commit 0c191634beceb6fdef0e8bf7b04cd549018736e7 @dizzzz dizzzz committed Aug 11, 2014
Showing with 37 additions and 27 deletions.
  1. +37 −27 src/org/exist/storage/XQueryPool.java
@@ -168,34 +168,44 @@ private synchronized void returnObject(Source source, Object o) {
}
}
- private synchronized Object borrowObject(DBBroker broker, Source source) {
- final int idx = getIndex(source);
- if (idx < 0) {
- return null;
- }
- final Source key = (Source) keys[idx];
- int validity = key.isValid(broker);
-
- if (validity == Source.UNKNOWN)
- validity = key.isValid(source);
-
- if (validity == Source.INVALID || validity == Source.UNKNOWN) {
- keys[idx] = REMOVED;
- values[idx] = null;
- LOG.debug(source.getKey() + " is invalid");
- return null;
- }
-
- final Stack stack = (Stack) values[idx];
- if (stack == null || stack.isEmpty())
- return null;
+ private Object borrowObject(DBBroker broker, Source source) {
+
+ CompiledXQuery query = null;
+ Source key = null;
+
+ synchronized (this) {
+ final int idx = getIndex(source);
+ if (idx < 0) {
+ return null;
+ }
+ key = (Source) keys[idx];
+ int validity = key.isValid(broker);
+ if (validity == Source.UNKNOWN)
+ validity = key.isValid(source);
+
+ if (validity == Source.INVALID || validity == Source.UNKNOWN) {
+ keys[idx] = REMOVED;
+ values[idx] = null;
+ LOG.debug(source.getKey() + " is invalid");
+ return null;
+ }
+ final Stack stack = (Stack) values[idx];
+ if (stack == null || stack.isEmpty())
+ return null;
+
+ // now check if the compiled expression is valid
+ // it might become invalid if an imported module has changed.
+ query = (CompiledXQuery) stack.pop();
+ final XQueryContext context = query.getContext();
+ //context.setBroker(broker);
+ }
- // now check if the compiled expression is valid
- // it might become invalid if an imported module has changed.
- final CompiledXQuery query = (CompiledXQuery) stack.pop();
- //final XQueryContext context = query.getContext();
- //context.setBroker(broker);
- if (!query.isValid()) {
+ // query.isValid() may open collections which in turn tries to acquire
+ // org.exist.storage.lock.ReentrantReadWriteLock. In order to avoid
+ // deadlocks with concurrent queries holding that lock while borrowing
+ // we must not hold onto the XQueryPool while calling isValid().
+
+ if (!query.isValid()) synchronized (this) {
// the compiled query is no longer valid: one of the imported
// modules may have changed
remove(key);

0 comments on commit 0c19163

Please sign in to comment.