[ http://issues.apache.org/jira/browse/JCR-546?page=all ]

Jukka Zitting updated JCR-546:
------------------------------

    Attachment: JCR-546.patch

Attached a proposed patch for fixing this and the related JCR-632.

The problem with just switching the order of the read and write lock operations 
is that then the underlying state that was read during the first half of the 
checkin() state may already have been modified when the second half persists 
the modifications.

The proposed resolution simply extends the write lock to guard the entire 
checkin() operation. This introduces a minor performance loss for concurrent 
reads, but avoids the deadlock.

The patch also introduces a WriteOperation helper class to simplify the 
following repeating code pattern:

    aquireWriteLock();
    try {
        stateMgr.edit();
    } catch (IllegalStateException e) {
        releaseWriteLock();
    }

    boolean success = false;
    try {
        ...
        stateMgr.save();
        success = true;
        ...
    } catch (...) {
        ...
    } finally {
        if (!success) {
            stateMgr.cancel();
        }
        releaseWriteLock();
    }

into this:

    WriteOperation operation = startWriteOperation();
    try {
        ...
        operation.save();
        ...
    } catch (...) {
        ...
    } finally {
        operation.close();
    }

The idea is to separate the locking and state manager handling from the general 
versioning logic.

I also fixed spelling from "aquire" to "acquire" and guarded even some trivial 
locked operations with try-finally to more gracefully handle unexpected 
conditions like NPEs.


> Deadlock during checkin
> -----------------------
>
>                 Key: JCR-546
>                 URL: http://issues.apache.org/jira/browse/JCR-546
>             Project: Jackrabbit
>          Issue Type: Bug
>          Components: versioning
>         Environment: WinXP Jackrabbit r431916
>            Reporter: Rod Mackenzie
>         Assigned To: Tobias Bocanegra
>         Attachments: JCR-546.patch
>
>
> Under a load of 3 threads performing checkin and restore operations it's 
> possible for all to become deadlocked in AbstractVersionManager.checkin(). 
> This method attempts to upgrade a read lock to a write lock with the 
> following code
>     aquireReadLock();
>     ....
>     try {
>         aquireWriteLock();
>         releaseReadLock();
>         ...
> If 2 or more threads acquire the read lock then neither can acquire the write 
> lock resulting in the deadlock, and after that any other thread that calls 
> this method will block waiting for the write lock. The release of the read 
> lock needs to be done before acquiring the write lock, this is documented 
> Concurrent library javadoc.
> There is another area where there is an attempt to upgrade a read lock to 
> write lock, RepositoryImpl.WorkspaceInfo.disposeIfIdle() acquires a read lock 
> and calls dispose() which then acquires a write lock, this maybe ok, as I 
> assume there is only 1 thread that will attempt to dispose of idle workspaces.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to