HHH-15541 Possible carrier thread pinning synchronized blocks migrated to ReentrantLock
This commit is contained in:
parent
67cdd0b28a
commit
93dc0aecf3
|
@ -109,10 +109,12 @@ public class StandardServiceRegistryImpl extends AbstractServiceRegistryImpl imp
|
|||
* Not intended for general use. We need the ability to stop and "reactivate" a registry to allow
|
||||
* experimentation with technologies such as GraalVM, Quarkus and Cri-O.
|
||||
*/
|
||||
public synchronized void resetAndReactivate(BootstrapServiceRegistry bootstrapServiceRegistry,
|
||||
public void resetAndReactivate(BootstrapServiceRegistry bootstrapServiceRegistry,
|
||||
List<StandardServiceInitiator<?>> serviceInitiators,
|
||||
List<ProvidedService<?>> providedServices,
|
||||
Map<?, ?> configurationValues) {
|
||||
thisLock.lock();
|
||||
try {
|
||||
if ( super.isActive() ) {
|
||||
throw new IllegalStateException( "Can't reactivate an active registry" );
|
||||
}
|
||||
|
@ -120,25 +122,43 @@ public class StandardServiceRegistryImpl extends AbstractServiceRegistryImpl imp
|
|||
this.configurationValues = new HashMap( configurationValues );
|
||||
super.reactivate();
|
||||
applyServiceRegistrations( serviceInitiators, providedServices );
|
||||
} finally {
|
||||
thisLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized <R extends Service> R initiateService(ServiceInitiator<R> serviceInitiator) {
|
||||
public <R extends Service> R initiateService(ServiceInitiator<R> serviceInitiator) {
|
||||
thisLock.lock();
|
||||
try {
|
||||
// todo : add check/error for unexpected initiator types?
|
||||
return ( (StandardServiceInitiator<R>) serviceInitiator ).initiateService( configurationValues, this );
|
||||
} finally {
|
||||
thisLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized <R extends Service> void configureService(ServiceBinding<R> serviceBinding) {
|
||||
public <R extends Service> void configureService(ServiceBinding<R> serviceBinding) {
|
||||
thisLock.lock();
|
||||
try {
|
||||
if ( serviceBinding.getService() instanceof Configurable ) {
|
||||
( (Configurable) serviceBinding.getService() ).configure( configurationValues );
|
||||
}
|
||||
} finally {
|
||||
thisLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void destroy() {
|
||||
public void destroy() {
|
||||
thisLock.lock();
|
||||
try {
|
||||
super.destroy();
|
||||
this.configurationValues = null;
|
||||
} finally {
|
||||
thisLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ package org.hibernate.cache.spi;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||
import org.hibernate.cache.CacheException;
|
||||
|
@ -46,6 +48,7 @@ public abstract class AbstractRegionFactory implements RegionFactory {
|
|||
|
||||
private SessionFactoryOptions options;
|
||||
|
||||
protected final Lock thisLock = new ReentrantLock();
|
||||
|
||||
protected boolean isStarted() {
|
||||
if ( started.get() ) {
|
||||
|
@ -83,7 +86,8 @@ public abstract class AbstractRegionFactory implements RegionFactory {
|
|||
@Override
|
||||
public final void start(SessionFactoryOptions settings, Map<String,Object> configValues) throws CacheException {
|
||||
if ( started.compareAndSet( false, true ) ) {
|
||||
synchronized (this) {
|
||||
thisLock.lock();
|
||||
try {
|
||||
this.options = settings;
|
||||
try {
|
||||
prepareForUse( settings, configValues );
|
||||
|
@ -94,6 +98,8 @@ public abstract class AbstractRegionFactory implements RegionFactory {
|
|||
started.set( false );
|
||||
startingException = e;
|
||||
}
|
||||
} finally {
|
||||
thisLock.unlock();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -106,7 +112,8 @@ public abstract class AbstractRegionFactory implements RegionFactory {
|
|||
@Override
|
||||
public final void stop() {
|
||||
if ( started.compareAndSet( true, false ) ) {
|
||||
synchronized ( this ) {
|
||||
thisLock.lock();
|
||||
try {
|
||||
try {
|
||||
releaseFromUse();
|
||||
}
|
||||
|
@ -114,6 +121,8 @@ public abstract class AbstractRegionFactory implements RegionFactory {
|
|||
options = null;
|
||||
startingException = null;
|
||||
}
|
||||
} finally {
|
||||
thisLock.unlock();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -14,6 +14,8 @@ import java.util.Set;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
||||
|
@ -72,6 +74,9 @@ public abstract class AbstractServiceRegistryImpl
|
|||
|
||||
private final AtomicBoolean active = new AtomicBoolean( true );
|
||||
|
||||
protected final Lock thisLock = new ReentrantLock();
|
||||
private final Lock serviceBindingListLock = new ReentrantLock();
|
||||
|
||||
protected AbstractServiceRegistryImpl(@Nullable ServiceRegistryImplementor parent) {
|
||||
this( parent, true );
|
||||
}
|
||||
|
@ -199,7 +204,8 @@ public abstract class AbstractServiceRegistryImpl
|
|||
}
|
||||
|
||||
//Any service initialization needs synchronization
|
||||
synchronized ( this ) {
|
||||
thisLock.lock();
|
||||
try {
|
||||
// Check again after having acquired the lock:
|
||||
service = serviceRole.cast( initializedServiceByRole.get( serviceRole ) );
|
||||
if ( service != null ) {
|
||||
|
@ -219,13 +225,18 @@ public abstract class AbstractServiceRegistryImpl
|
|||
initializedServiceByRole.put( serviceRole, service );
|
||||
}
|
||||
return service;
|
||||
} finally {
|
||||
thisLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
protected <R extends Service> void registerService(ServiceBinding<R> serviceBinding, R service) {
|
||||
serviceBinding.setService( service );
|
||||
synchronized ( serviceBindingList ) {
|
||||
serviceBindingListLock.lock();
|
||||
try {
|
||||
serviceBindingList.add( serviceBinding );
|
||||
} finally {
|
||||
serviceBindingListLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -351,13 +362,16 @@ public abstract class AbstractServiceRegistryImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized void destroy() {
|
||||
public void destroy() {
|
||||
thisLock.lock();
|
||||
try {
|
||||
if ( active.compareAndSet( true, false ) ) {
|
||||
try {
|
||||
//First thing, make sure that the fast path read is disabled so that
|
||||
//threads not owning the synchronization lock can't get an invalid Service:
|
||||
initializedServiceByRole.clear();
|
||||
synchronized (serviceBindingList) {
|
||||
serviceBindingListLock.lock();
|
||||
try {
|
||||
ListIterator<ServiceBinding<?>> serviceBindingsIterator = serviceBindingList.listIterator(
|
||||
serviceBindingList.size()
|
||||
);
|
||||
|
@ -366,6 +380,8 @@ public abstract class AbstractServiceRegistryImpl
|
|||
serviceBinding.getLifecycleOwner().stopService( serviceBinding );
|
||||
}
|
||||
serviceBindingList.clear();
|
||||
} finally {
|
||||
serviceBindingListLock.unlock();
|
||||
}
|
||||
serviceBindingMap.clear();
|
||||
}
|
||||
|
@ -375,10 +391,15 @@ public abstract class AbstractServiceRegistryImpl
|
|||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
thisLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized <R extends Service> void stopService(ServiceBinding<R> binding) {
|
||||
public <R extends Service> void stopService(ServiceBinding<R> binding) {
|
||||
thisLock.lock();
|
||||
try {
|
||||
final Service service = binding.getService();
|
||||
if ( service instanceof Stoppable ) {
|
||||
try {
|
||||
|
@ -388,10 +409,15 @@ public abstract class AbstractServiceRegistryImpl
|
|||
log.unableToStopService( service.getClass(), e );
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
thisLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void registerChild(ServiceRegistryImplementor child) {
|
||||
public void registerChild(ServiceRegistryImplementor child) {
|
||||
thisLock.lock();
|
||||
try {
|
||||
if ( childRegistries == null ) {
|
||||
childRegistries = new HashSet<>();
|
||||
}
|
||||
|
@ -401,10 +427,15 @@ public abstract class AbstractServiceRegistryImpl
|
|||
child
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
thisLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void deRegisterChild(ServiceRegistryImplementor child) {
|
||||
public void deRegisterChild(ServiceRegistryImplementor child) {
|
||||
thisLock.lock();
|
||||
try {
|
||||
if ( childRegistries == null ) {
|
||||
throw new IllegalStateException( "No child ServiceRegistry registrations found" );
|
||||
}
|
||||
|
@ -424,13 +455,18 @@ public abstract class AbstractServiceRegistryImpl
|
|||
);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
thisLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Not intended for general use. We need the ability to stop and "reactivate" a registry to allow
|
||||
* experimentation with technologies such as GraalVM, Quarkus and Cri-O.
|
||||
*/
|
||||
public synchronized void resetParent(@Nullable BootstrapServiceRegistry newParent) {
|
||||
public void resetParent(@Nullable BootstrapServiceRegistry newParent) {
|
||||
thisLock.lock();
|
||||
try {
|
||||
if ( this.parent != null ) {
|
||||
this.parent.deRegisterChild( this );
|
||||
}
|
||||
|
@ -444,6 +480,9 @@ public abstract class AbstractServiceRegistryImpl
|
|||
else {
|
||||
this.parent = null;
|
||||
}
|
||||
} finally {
|
||||
thisLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -477,10 +516,15 @@ public abstract class AbstractServiceRegistryImpl
|
|||
* Not intended for general use. We need the ability to stop and "reactivate" a registry to allow
|
||||
* experimentation with technologies such as GraalVM, Quarkus and Cri-O.
|
||||
*/
|
||||
public synchronized void reactivate() {
|
||||
public void reactivate() {
|
||||
thisLock.lock();
|
||||
try {
|
||||
if ( !active.compareAndSet( false, true ) ) {
|
||||
throw new IllegalStateException( "Was not inactive, could not reactivate" );
|
||||
}
|
||||
} finally {
|
||||
thisLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue