@@ -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