jackrabbit-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Lukas Eder (JIRA)" <j...@apache.org>
Subject [jira] [Created] (JCR-3541) Non-negligible probability of deadlock between AbstractCompiledPermissions.monitor and other actors
Date Mon, 25 Mar 2013 16:37:16 GMT
Lukas Eder created JCR-3541:
-------------------------------

             Summary: Non-negligible probability of deadlock between AbstractCompiledPermissions.monitor
and other actors
                 Key: JCR-3541
                 URL: https://issues.apache.org/jira/browse/JCR-3541
             Project: Jackrabbit Content Repository
          Issue Type: Bug
          Components: jackrabbit-core
    Affects Versions: 2.5.3
            Reporter: Lukas Eder


There is a high probability of a deadlock between org.apache.jackrabbit.core.security.authorization.AbstractCompiledPermissions
and other actors in jackrabbit-core's internals. The problem lies in the fact that AbstractCompiledPermissions.getResult()
holds the monitor for quite a long time:

        synchronized (monitor) {
            result = cache.get(absPath);
            if (result == null) {
                if (absPath == null) {
                    result = buildRepositoryResult();
                } else {
                    result = buildResult(absPath); // Slow operation
                }
                cache.put(absPath, result);
            }
        }

Implementations might run lots of code within buildResult(), which may eventually invoke the
synchronized ItemManager methods, for instance, which themselves have a significant probability
of passing through the AbstractCompiledPermissions again.

I wonder whether synchronization should be limited to cache access, applying double-checked
locking as such:

        Result result;
        synchronized (monitor) {
            result = cache.get(absPath);
        }
        if (result == null) {
            if (absPath == null) {
                result = buildRepositoryResult();
            } else {
                result = buildResult(absPath);
            }

            synchronized (monitor) {
                Result r = cache.get(absPath);
                if (r == null) {
                    cache.put(absPath, result);
                }
            }
        }
        return result;

Alternatively, to make things a bit more readable, the cache could be implemented using a
ConcurrentHashMap.

Note, the actual deadlock that I've got was probably due to abusing the Jackrabbit APIs in
a custom AccessControlProvider

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Mime
View raw message