[ https://issues.apache.org/jira/browse/QPID-8554?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Marek Laca updated QPID-8554: ----------------------------- Description: The CachingSecurityToken class is caching the authorization results. It can be utilized by multiple threads at the same time. Hence, it has to be multi-thread safe. The CachingSecurityToken::authorise could get stuck in an infinite loop when multiple threads try to update the local cache simultaneously. Two threads can be in permanent conflict when each thread is trying to override changes of another thread. {code:java} AccessControlCache cache; while((cache = CACHE_UPDATE.get(this)).getAccessControl() != ruleBasedAccessControl) { CACHE_UPDATE.compareAndSet(this, cache, new AccessControlCache(ruleBasedAccessControl)); } {code} Suppose two threads, the thread A and B in following scenario with steps: The thread A run into the loop: 1. Thread A checks the condition and the 'accessControl' in the cache differs from its local value 'ruleBasedAccessControl', let label it as accessControlA. 2. Thread A updates the cache with local value accessControlA. The thread B run into the loop: 3. Thread B checks the condition and the 'accessControl' in the cache differs from its local value 'ruleBasedAccessControl', let label it as accessControlB. 4. Thread B updates the cache with local value accessControlB. The thread A starts the next iteration of the loop: 5. Thread A checks the condition and the 'accessControl' in the cache is accessControlB, it differs from its local value accessControlA. 6. Thread A updates the cache with local value accessControlA. The thread B starts the next iteration of the loop: 7. Thread B checks the condition and the 'accessControl' in the cache is accessControlA, it differs from its local value accessControlB. 8. Thread B updates the cache with local value accessControlB. The steps 5-8 can repeat forever. Each thread finds in the cache the value from another thread and update cache with its own. The code does not have any guarantee after how many iterations the loop ends. The probability of the endless competition increases with number of threads. was: The CachingSecurityToken class is caching the authorization results. It can be utilized by multiple threads at the same time. Hence, it has to be multi-thread safe. The CachingSecurityToken::authorise could get stuck in an infinite loop when multiple threads try to update the local cache simultaneously. Two threads can be in permanent conflict when each thread is trying to override changes of another thread. {code:java} AccessControlCache cache; while((cache = CACHE_UPDATE.get(this)).getAccessControl() != ruleBasedAccessControl) { CACHE_UPDATE.compareAndSet(this, cache, new AccessControlCache(ruleBasedAccessControl)); } {code} > [Broker-J] Infinite loop in CachingSecurityToken class > ------------------------------------------------------ > > Key: QPID-8554 > URL: https://issues.apache.org/jira/browse/QPID-8554 > Project: Qpid > Issue Type: Bug > Components: Broker-J > Reporter: Marek Laca > Priority: Minor > Labels: Broker, Java, thread-safe > > The CachingSecurityToken class is caching the authorization results. It can > be utilized by multiple threads at the same time. Hence, it has to be > multi-thread safe. The CachingSecurityToken::authorise could get stuck in an > infinite loop when multiple threads try to update the local cache > simultaneously. > Two threads can be in permanent conflict when each thread is trying to > override changes of another thread. > {code:java} > AccessControlCache cache; > while((cache = CACHE_UPDATE.get(this)).getAccessControl() != > ruleBasedAccessControl) > { > CACHE_UPDATE.compareAndSet(this, cache, new > AccessControlCache(ruleBasedAccessControl)); > } > {code} > Suppose two threads, the thread A and B in following scenario with steps: > The thread A run into the loop: > 1. Thread A checks the condition and the 'accessControl' in the cache differs > from its local value 'ruleBasedAccessControl', let label it as accessControlA. > 2. Thread A updates the cache with local value accessControlA. > The thread B run into the loop: > 3. Thread B checks the condition and the 'accessControl' in the cache differs > from its local value 'ruleBasedAccessControl', let label it as accessControlB. > 4. Thread B updates the cache with local value accessControlB. > The thread A starts the next iteration of the loop: > 5. Thread A checks the condition and the 'accessControl' in the cache is > accessControlB, it differs from its local value accessControlA. > 6. Thread A updates the cache with local value accessControlA. > The thread B starts the next iteration of the loop: > 7. Thread B checks the condition and the 'accessControl' in the cache is > accessControlA, it differs from its local value accessControlB. > 8. Thread B updates the cache with local value accessControlB. > The steps 5-8 can repeat forever. Each thread finds in the cache the value > from another thread and update cache with its own. > The code does not have any guarantee after how many iterations the loop ends. > The probability of the endless competition increases with number of threads. -- This message was sent by Atlassian Jira (v8.3.4#803005) --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@qpid.apache.org For additional commands, e-mail: dev-h...@qpid.apache.org