public void open() throws IOException {
        if (!this.closed.get()) { throw new IOException("queue already opened"); }

        lock.lock();
        try {
            try {
                // verify exclusive access to the dirPath
                this.dirLock = FileLockFactory.obtainLock(this.dirPath, LOCK_NAME);
            } catch (LockException e) {
                throw new LockException("The queue failed to obtain exclusive access, cause: " + e.getMessage());
            }

            try {
                openPages();
                this.closed.set(false);
            } catch (IOException e) {
                // upon any exception while opening the queue and after dirlock has been obtained
                // we need to make sure to release the dirlock. Calling the close method on a partially
                // open queue has no effect because the closed flag is still true.
                releaseLockAndSwallow();
                throw(e);
            }
        } finally {
            lock.unlock();
        }
    }
@Test
    public void lockIsReleasedUponOpenException() throws Exception {
        Settings settings = SettingsImpl.builder(TestSettings.persistedQueueSettings(100, dataPath))
                .queueMaxBytes(Long.MAX_VALUE)
                .build();
        try {
            Queue queue = new Queue(settings);
            queue.open();
            fail("expected queue.open() to throws when not enough disk free");
        } catch (IOException e) {
            assertThat(e.getMessage(), containsString("Unable to allocate"));
        }

        // at this point the Queue lock should be released and Queue.open should not throw a LockException
        try (Queue queue = new Queue(TestSettings.persistedQueueSettings(10, dataPath))) {
            queue.open();
        }
    }