EHC ❯ CacheManagerEventListenerRegistry is not thread-safe
-
Bug
-
Status: Closed
-
2 Major
-
Resolution: Fixed
-
ehcache-core
-
-
hsingh
-
Reporter: amiller
-
December 15, 2009
-
0
-
Watchers: 1
-
January 17, 2013
-
January 06, 2010
Description
This class contains shared state (the listeners Set) that can be modified by multiple threads. Usually the listeners are installed primarily during CacheManager construction so that (common) path is ok due to safe publication. However, the listener registry can be obtained at any time from CacheManager.getCacheManagerEventListenerRegistry() and any thread may be reading or writing the state of it.
This is probably easy to fix by simplying changing from HashSet to CopyOnWriteArraySet.
This class also has a status field that is set to STATUS_UNINITIALISED but never modified after that. This is neither thread-safe (due to visibility) nor useful. :) This should probably be changed to volatile and the status changes actually implemented OR simply removed altogether (including getStatus()).
Comments
Hung Huynh 2010-01-06
Lorenzo Resta 2010-03-17
It looks like a bug is related to this issue: During shutdown of the cacheManager or when a cachelistener is deregistered an java.langUnsupportedException is thrown:
See http://forums.terracotta.org/forums/posts/list/3306.page or http://forums.terracotta.org/forums/posts/list/3307.page or http://forums.terracotta.org/forums/posts/list/3304.page
It lools like during deregistration of the cachelisteners a java.lang.UnsupportedOperationException is thrown. This is happening because the remove() method of the COWIterator of the CopyOnWriteArrayList class is not supported!
java.lang.UnsupportedOperationException at java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove(CopyOnWriteArrayList.java:1004) at net.sf.ehcache.event.RegisteredEventListeners.unregisterListener(RegisteredEventListeners.java:247) at ch.deltaenergy.collections.AbstractCollection$CacheExpiryListener.dispose(AbstractCollection.java:511) at net.sf.ehcache.event.RegisteredEventListeners.dispose(RegisteredEventListeners.java:275) at net.sf.ehcache.Cache.dispose(Cache.java:2085) at net.sf.ehcache.CacheManager.shutdown(CacheManager.java:1033)
replaced HashSet with CopyOnWriteArraySet to hold the listeners set status field to volatile and properly set it to STATUS_LIVE on init(), and STATUS_SHUTDOWN on dispose()