Skip to content

Commit 00e6099

Browse files
authored
GH-4817 LMDB: Make close method of LmdbRecordIterator thread-safe. (#4818)
2 parents d81918d + cbeeabb commit 00e6099

1 file changed

Lines changed: 31 additions & 14 deletions

File tree

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbRecordIterator.java

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class LmdbRecordIterator implements RecordIterator {
5454

5555
private final int dbi;
5656

57-
private boolean closed = false;
57+
private volatile boolean closed = false;
5858

5959
private final MDBVal keyData;
6060

@@ -72,6 +72,8 @@ class LmdbRecordIterator implements RecordIterator {
7272

7373
private final StampedLock txnLock;
7474

75+
private final Thread ownerThread = Thread.currentThread();
76+
7577
LmdbRecordIterator(Pool pool, TripleIndex index, boolean rangeSearch, long subj, long pred, long obj,
7678
long context, boolean explicit, Txn txnRef) throws IOException {
7779
this.pool = pool;
@@ -140,7 +142,7 @@ public long[] next() throws IOException {
140142
lastResult = mdb_cursor_get(cursor, keyData, valueData, MDB_SET_RANGE);
141143
}
142144
if (lastResult != 0) {
143-
close();
145+
closeInternal(false);
144146
return null;
145147
}
146148
}
@@ -177,30 +179,45 @@ public long[] next() throws IOException {
177179
return quad;
178180
}
179181
}
180-
close();
182+
closeInternal(false);
181183
return null;
182184
} finally {
183185
txnLock.unlockRead(stamp);
184186
}
185187
}
186188

187-
@Override
188-
public void close() throws IOException {
189+
private void closeInternal(boolean maybeCalledAsync) {
189190
if (!closed) {
191+
long stamp;
192+
if (maybeCalledAsync && ownerThread != Thread.currentThread()) {
193+
stamp = txnLock.writeLock();
194+
} else {
195+
stamp = 0;
196+
}
190197
try {
191-
mdb_cursor_close(cursor);
192-
pool.free(keyData);
193-
pool.free(valueData);
194-
if (minKeyBuf != null) {
195-
pool.free(minKeyBuf);
196-
}
197-
if (maxKey != null) {
198-
pool.free(maxKeyBuf);
199-
pool.free(maxKey);
198+
if (!closed) {
199+
mdb_cursor_close(cursor);
200+
pool.free(keyData);
201+
pool.free(valueData);
202+
if (minKeyBuf != null) {
203+
pool.free(minKeyBuf);
204+
}
205+
if (maxKey != null) {
206+
pool.free(maxKeyBuf);
207+
pool.free(maxKey);
208+
}
200209
}
201210
} finally {
202211
closed = true;
212+
if (stamp != 0) {
213+
txnLock.unlockWrite(stamp);
214+
}
203215
}
204216
}
205217
}
218+
219+
@Override
220+
public void close() throws IOException {
221+
closeInternal(true);
222+
}
206223
}

0 commit comments

Comments
 (0)