@Override public void readExtraCommitData(byte[] extra) throws IOException { try { mHeaderLatch.acquireShared(); try { readPartial(mCommitNumber & 1, I_EXTRA_DATA, extra, 0, extra.length); } finally { mHeaderLatch.releaseShared(); } } catch (Throwable e) { throw closeOnFailure(e); } }
/** @see _SnapshotPageArray#beginSnapshot */ Snapshot beginSnapshot(_LocalDatabase db) throws IOException { mHeaderLatch.acquireShared(); try { long pageCount, redoPos; long header = p_alloc(MINIMUM_PAGE_SIZE); try { mPageArray.readPage(mCommitNumber & 1, header, 0, MINIMUM_PAGE_SIZE); pageCount = _PageManager.readTotalPageCount(header, I_MANAGER_HEADER); redoPos = _LocalDatabase.readRedoPosition(header, I_EXTRA_DATA); } finally { p_delete(header); } return mPageArray.beginSnapshot(db, pageCount, redoPos); } finally { mHeaderLatch.releaseShared(); } }
@Override public void commit(boolean resume, long header, final CommitCallback callback) throws IOException { // Acquire a shared lock to prevent concurrent commits after callback has released // exclusive lock. CommitLock.Shared shared = mCommitLock.acquireShared(); try { mHeaderLatch.acquireShared(); final int commitNumber = mCommitNumber + 1; mHeaderLatch.releaseShared(); try { if (!resume) { mPageManager.commitStart(header, I_MANAGER_HEADER); } if (callback != null) { // Invoke the callback to ensure all dirty pages get written. callback.prepare(resume, header); } } catch (DatabaseException e) { if (e.isRecoverable()) { throw e; } else { throw closeOnFailure(e); } } try { commitHeader(header, commitNumber); mPageManager.commitEnd(header, I_MANAGER_HEADER); } catch (Throwable e) { throw closeOnFailure(e); } } finally { shared.release(); } }