Component base classes aren't completely thread-safe
Basics
Logistics
Basics
Logistics
Description
The abstract base classes supplied for the component system aren't strictly compatible with full thread-safety because access to the state they control isn't fully synchronized.
This isn't a problem for components which are @ThreadSafeAfterInit but it does prevent even in principle the building of components which are truly @ThreadSafe.
I think it's relatively cheap to fix this, so that these base classes can be used for either kind of component:
In AbstractIdentifiedInitializableComponent:
The id field should be @GuardedBy("this")
Both getId and setId should be synchronized
In AbstractInitializableComponent:
The isDestroyed field should be @GuardedBy("this")
The isInitialized field should be @GuardedBy("this")
The isDestroyed and isInitialized methods should both be synchronized
The {{@GuardedBy}} annotations are just documentation.
The isInitialized and isDestroyed methods are generally only called before the object becomes live, so I think any synchronization overhead can be ignored in practice.
Today's developer call: do this, and add @ThreadSafe, once we have branched things for the IdP 4.1 release.
Make a new issue for the final change, with the expectation of targeting it to IdP 5.0.
Ian YoungJune 5, 2020 at 1:28 PM
Other considerations:
Worth marking these (abstract) classes as @ThreadSafe now that they actually are?
Worth marking the getters (and maybe also the setters) as final so that the compiler can optimise their use a bit more? I guess that would be an API change, but I can't imagine anyone actually overrides these in subclasses in practice. There's bound to be one...
The abstract base classes supplied for the component system aren't strictly compatible with full thread-safety because access to the state they control isn't fully synchronized.
This isn't a problem for components which are
@ThreadSafeAfterInit
but it does prevent even in principle the building of components which are truly@ThreadSafe
.I think it's relatively cheap to fix this, so that these base classes can be used for either kind of component:
In
AbstractIdentifiedInitializableComponent
:The
id
field should be@GuardedBy("this")
Both
getId
andsetId
should besynchronized
In
AbstractInitializableComponent
:The
isDestroyed
field should be@GuardedBy("this")
The
isInitialized
field should be@GuardedBy("this")
The
isDestroyed
andisInitialized
methods should both besynchronized
The {{@GuardedBy}} annotations are just documentation.
The
isInitialized
andisDestroyed
methods are generally only called before the object becomes live, so I think any synchronization overhead can be ignored in practice.