Skip to content

Commit

Permalink
Makes DeferredNamedList thread safe to prevent concurrent modificatio…
Browse files Browse the repository at this point in the history
…ns exceptions.

git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@549 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
lucboudreau committed Sep 28, 2012
1 parent 5913e32 commit c5f9dfc
Showing 1 changed file with 27 additions and 17 deletions.
44 changes: 27 additions & 17 deletions src/org/olap4j/driver/xmla/DeferredNamedListImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import java.util.AbstractList;
import java.util.Map;
import java.util.concurrent.Semaphore;

/**
* Named list which instantiates itself on first use.
Expand Down Expand Up @@ -57,6 +58,7 @@ class DeferredNamedListImpl<T extends Named>
protected final XmlaOlap4jConnection.Context context;
protected final XmlaOlap4jConnection.Handler<T> handler;
protected final Object[] restrictions;
protected final Semaphore semaphore = new Semaphore(1);

DeferredNamedListImpl(
XmlaOlap4jConnection.MetadataRequest metadataRequest,
Expand All @@ -80,24 +82,32 @@ void reset() {
}

private NamedList<T> getList() {
switch (state) {
case POPULATING:
throw new RuntimeException("recursive population");
case NEW:
try {
state = State.POPULATING;
populateList(list);
state = State.POPULATED;
} catch (OlapException e) {
state = State.NEW;
// TODO: fetch metadata on getCollection() method, so we
// can't get an exception while traversing the list
throw new RuntimeException(e);
try {
semaphore.acquire();
switch (state) {
case POPULATING:
throw new RuntimeException("recursive population");
case NEW:
try {
state = State.POPULATING;
populateList(list);
state = State.POPULATED;
} catch (OlapException e) {
state = State.NEW;
// TODO: fetch metadata on getCollection() method, so we
// can't get an exception while traversing the list
throw new RuntimeException(e);
}
// fall through
case POPULATED:
default:
return list;
}
// fall through
case POPULATED:
default:
return list;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} finally {
semaphore.release();
}
}

Expand Down

0 comments on commit c5f9dfc

Please sign in to comment.