Uploaded image for project: 'Jackrabbit Content Repository'
  1. Jackrabbit Content Repository
  2. JCR-3888

Possible dead lock in SharedItemStateManager in clustered environment

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 2.10.1
    • 2.10.2, 2.11.0
    • None
    • None

    Description

      When using clustering SharedItemStateManager#Update#begin sets a lock on the database (line 573) and subsequently a write lock is set (line 579):

                  // let listener know about change
                  try {
                      eventChannel.updateCreated(this); // line 573
                  } catch (ClusterException e) {
                      throw new ItemStateException(e.getMessage(), e);
                  }
      
                  try {
                      writeLock = acquireWriteLock(local); // line 579
                  } finally {
                      if (writeLock == null) {
                          eventChannel.updateCancelled(this); // line 582
                      }
                  }
      

      In SharedItemStateManager#Update#end the update is committed and the write lock released:

                      eventChannel.updateCommitted(this, path); // line 849
                      setAttribute(ATTRIBUTE_UPDATE_SIZE, null);
      
                      if (writeLock != null) {
                          // exception occurred before downgrading lock
                          writeLock.release();
                          writeLock = null;
                      } else if (readLock != null) {
                          try {
                              if (succeeded) {
                                  /* dispatch the events */
                                  events.dispatch();
                              }
                          } finally {
                              readLock.release(); // 863
                          }
                      }
      

      However, the implementation of eventChannel#updateCommitted in ClusterNode#WorkspaceUpdateChannel#updateCommitted has the following code:

                      long journalUpdateSize = record.update(); // line 700
      
                      long recordRevision = record.getRevision();
                      setRevision(recordRevision); // line 703
      

      The database lock is freed during the call to update the record on line 700.
      If a contending thread now sets a database lock at SharedItemStateManager:573 before this thread can set the revision in the database at ClusterNode:703 we have a dead lock. This is because this thread holds the write lock in SharedItemStateManager causing the contending thread to wait at SharedItemStateManager:579 while the contending thread holds the database lock causing this thread to wait at ClusterNode:703

      Attachments

        Activity

          People

            unico@apache.org Unico Hommes
            unico@apache.org Unico Hommes
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: