GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — SIGSEGV on `cursorIterable.next()` when the env is closed · Issue #185 · lmdbjava/lmdbjava Closed Labels DescriptionWe have a use case where LMDB envs are created as transient stores for search result data so are created, filled, queried then closed and deleted when no longer needed. There are multiple threads involved. We had a bug in our app that resulted in the env being closed while a thread was still trying to query the lmdb db. This resulted in a SIGSEGV and our whole app going down. I appreciate that querying the db after the env is closed is wrong, but it would be preferable to get an exception rather than have the whole app crash. I added the following test to @Test public void cannotReadOnceClosed() throws IOException, InterruptedException, ExecutionException { final File path = tmp.newFile(); final Env<ByteBuffer> env = create() .setMaxReaders(5) .open(path, MDB_NOSUBDIR); final Dbi<ByteBuffer> dbi = env.openDbi(DB_1, MDB_CREATE); dbi.put(bb(1), bb(10)); dbi.put(bb(2), bb(20)); try (Txn<ByteBuffer> roTxn = env.txnRead()) { assertThat(dbi.get(roTxn, bb(1)).getInt(), is(10)); assertThat(dbi.get(roTxn, bb(2)).getInt(), is(20)); } System.out.println("Done puts"); final CountDownLatch firstGetFinishedLatch = new CountDownLatch(1); final CountDownLatch envClosedLatch = new CountDownLatch(1); final CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { System.out.println("Running async task"); try (Txn<ByteBuffer> roTxn = env.txnRead()) { try (CursorIterable<ByteBuffer> iterable = dbi.iterate(roTxn, KeyRange.all())) { final Iterator<CursorIterable.KeyVal<ByteBuffer>> iterator = iterable.iterator(); try { System.out.println("Getting first entry"); CursorIterable.KeyVal<ByteBuffer> keyVal = iterator.next(); assertThat(keyVal.val().getInt(), is(10)); firstGetFinishedLatch.countDown(); try { System.out.println("Waiting for env to close"); envClosedLatch.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e); } assertThat(env.isClosed(), is(true)); System.out.println("Getting second entry, but env is now closed"); keyVal = iterator.next(); assertThat(keyVal.val().getInt(), is(20)); } catch (RuntimeException e) { e.printStackTrace(); } } } }); System.out.println("Waiting for cursor to get first entry"); firstGetFinishedLatch.await(); System.out.println("Closing env"); env.close(); envClosedLatch.countDown(); System.out.println("Waiting for completion"); future.get(); } This produces the output I have raised PR #186 with some added guards for the env being closed. Activity
MetadataMetadataAssigneesLabelsTypeProjectsMilestoneRelationshipsDevelopmentIssue actions |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |