Details
-
Bug
-
Status: Resolved
-
Blocker
-
Resolution: Fixed
-
0.9.10
Description
public ICachedPage pin(long dpid, IBufferCacheReadContext context) throws HyracksDataException { ... // Notify context page is going to be pinned context.onPin(cPage); <---- COULD ACQUIRE A READ LOCK // Resolve race of multiple threads trying to read the page from // disk. synchronized (cPage) { if (!cPage.valid) { try { tryRead(cPage, context); <--- THIS COULD FAIL cPage.valid = true; } catch (Exception e) { LOGGER.log(ExceptionUtils.causedByInterrupt(e) ? Level.DEBUG : Level.WARN, "Failure while trying to read a page from disk", e); throw e; } finally { if (!cPage.valid) { unpin(cPage); <--- THE ISSUE IS HERE } } } } } else { cPage.valid = true; } .... return cPage; }
context.onPin(page) could acquire a read lock However, when tryRead() fails, the finally part unpins the page without using the proper context. Thus, the lock acquired by the calling context.onPin(page) will not be released by calling unpin(page) as the context isn't passed and a default context will be used, where context.onUnpin(page) is a NO OP.