2222import java .util .concurrent .atomic .AtomicReference ;
2323import java .util .concurrent .atomic .LongAdder ;
2424import java .util .concurrent .locks .LockSupport ;
25- import java .util .concurrent .locks .ReentrantLock ;
2625
2726import org .eclipse .rdf4j .common .annotation .InternalUseOnly ;
27+ import org .eclipse .rdf4j .common .concurrent .locks .ExclusiveReentrantLockManager ;
2828import org .eclipse .rdf4j .common .concurrent .locks .Lock ;
2929import org .eclipse .rdf4j .common .concurrent .locks .diagnostics .ConcurrentCleaner ;
3030import org .eclipse .rdf4j .common .iteration .CloseableIteration ;
@@ -98,17 +98,16 @@ public abstract class AbstractSailConnection implements SailConnection {
9898 private final AtomicReference <Thread > activeThread = new AtomicReference <>();
9999
100100 @ SuppressWarnings ("FieldMayBeFinal" )
101- private boolean isOpen = true ;
101+ private volatile boolean isOpen = true ;
102102 private static final VarHandle IS_OPEN ;
103103
104104 private Thread owner ;
105105
106106 /**
107107 * Lock used to prevent concurrent calls to update methods like addStatement, clear, commit, etc. within a
108108 * transaction.
109- *
110109 */
111- private final ReentrantLock updateLock = new ReentrantLock ();
110+ private final ExclusiveReentrantLockManager updateLock = new ExclusiveReentrantLockManager ();
112111 private final LongAdder iterationsOpened = new LongAdder ();
113112 private final LongAdder iterationsClosed = new LongAdder ();
114113
@@ -200,8 +199,7 @@ public void begin(IsolationLevel isolationLevel) throws SailException {
200199 activeThread .setRelease (Thread .currentThread ());
201200
202201 verifyIsOpen ();
203-
204- updateLock .lock ();
202+ Lock exclusiveLock = updateLock .getExclusiveLock ();
205203 try {
206204 if (isActive ()) {
207205 throw new SailException ("a transaction is already active on this connection." );
@@ -210,8 +208,11 @@ public void begin(IsolationLevel isolationLevel) throws SailException {
210208 startTransactionInternal ();
211209 txnActive = true ;
212210 } finally {
213- updateLock . unlock ();
211+ exclusiveLock . release ();
214212 }
213+ } catch (InterruptedException e ) {
214+ Thread .currentThread ().interrupt ();
215+ throw new SailException (e );
215216 } finally {
216217 try {
217218 activeThread .setRelease (null );
@@ -505,15 +506,19 @@ public final void prepare() throws SailException {
505506 activeThread .setRelease (Thread .currentThread ());
506507 verifyIsOpen ();
507508
508- updateLock .lock ();
509+ Lock exclusiveLock = updateLock .getExclusiveLock ();
510+
509511 try {
510512 if (txnActive ) {
511513 prepareInternal ();
512514 txnPrepared = true ;
513515 }
514516 } finally {
515- updateLock . unlock ();
517+ exclusiveLock . release ();
516518 }
519+ } catch (InterruptedException e ) {
520+ Thread .currentThread ().interrupt ();
521+ throw new SailException (e );
517522 } finally {
518523 try {
519524 activeThread .setRelease (null );
@@ -535,7 +540,8 @@ public final void commit() throws SailException {
535540
536541 verifyIsOpen ();
537542
538- updateLock .lock ();
543+ Lock exclusiveLock = updateLock .getExclusiveLock ();
544+
539545 try {
540546 if (txnActive ) {
541547 if (!txnPrepared ) {
@@ -546,8 +552,11 @@ public final void commit() throws SailException {
546552 txnPrepared = false ;
547553 }
548554 } finally {
549- updateLock . unlock ();
555+ exclusiveLock . release ();
550556 }
557+ } catch (InterruptedException e ) {
558+ Thread .currentThread ().interrupt ();
559+ throw new SailException (e );
551560 } finally {
552561 try {
553562 activeThread .setRelease (null );
@@ -572,7 +581,8 @@ public final void rollback() throws SailException {
572581
573582 verifyIsOpen ();
574583
575- updateLock .lock ();
584+ Lock exclusiveLock = updateLock .getExclusiveLock ();
585+
576586 try {
577587 if (txnActive ) {
578588 try {
@@ -586,8 +596,11 @@ public final void rollback() throws SailException {
586596 debugEnabled ? new Throwable () : null );
587597 }
588598 } finally {
589- updateLock . unlock ();
599+ exclusiveLock . release ();
590600 }
601+ } catch (InterruptedException e ) {
602+ Thread .currentThread ().interrupt ();
603+ throw new SailException (e );
591604 } finally {
592605 try {
593606 activeThread .setRelease (null );
@@ -694,13 +707,17 @@ public final void endUpdate(UpdateContext op) throws SailException {
694707
695708 verifyIsOpen ();
696709
697- updateLock .lock ();
710+ Lock exclusiveLock = updateLock .getExclusiveLock ();
711+
698712 try {
699713 verifyIsActive ();
700714 endUpdateInternal (op );
701715 } finally {
702- updateLock . unlock ();
716+ exclusiveLock . release ();
703717 }
718+ } catch (InterruptedException e ) {
719+ Thread .currentThread ().interrupt ();
720+ throw new SailException (e );
704721 } finally {
705722 try {
706723 activeThread .setRelease (null );
@@ -750,14 +767,18 @@ public final void clear(Resource... contexts) throws SailException {
750767
751768 verifyIsOpen ();
752769
753- updateLock .lock ();
770+ Lock exclusiveLock = updateLock .getExclusiveLock ();
771+
754772 try {
755773 verifyIsActive ();
756774 clearInternal (contexts );
757775 statementsRemoved = true ;
758776 } finally {
759- updateLock . unlock ();
777+ exclusiveLock . release ();
760778 }
779+ } catch (InterruptedException e ) {
780+ Thread .currentThread ().interrupt ();
781+ throw new SailException (e );
761782 } finally {
762783 try {
763784 activeThread .setRelease (null );
@@ -820,13 +841,17 @@ public final void setNamespace(String prefix, String name) throws SailException
820841
821842 verifyIsOpen ();
822843
823- updateLock .lock ();
844+ Lock exclusiveLock = updateLock .getExclusiveLock ();
845+
824846 try {
825847 verifyIsActive ();
826848 setNamespaceInternal (prefix , name );
827849 } finally {
828- updateLock . unlock ();
850+ exclusiveLock . release ();
829851 }
852+ } catch (InterruptedException e ) {
853+ Thread .currentThread ().interrupt ();
854+ throw new SailException (e );
830855 } finally {
831856 try {
832857 activeThread .setRelease (null );
@@ -848,13 +873,17 @@ public final void removeNamespace(String prefix) throws SailException {
848873
849874 verifyIsOpen ();
850875
851- updateLock .lock ();
876+ Lock exclusiveLock = updateLock .getExclusiveLock ();
877+
852878 try {
853879 verifyIsActive ();
854880 removeNamespaceInternal (prefix );
855881 } finally {
856- updateLock . unlock ();
882+ exclusiveLock . release ();
857883 }
884+ } catch (InterruptedException e ) {
885+ Thread .currentThread ().interrupt ();
886+ throw new SailException (e );
858887 } finally {
859888 try {
860889 activeThread .setRelease (null );
@@ -873,13 +902,17 @@ public final void clearNamespaces() throws SailException {
873902
874903 verifyIsOpen ();
875904
876- updateLock .lock ();
905+ Lock exclusiveLock = updateLock .getExclusiveLock ();
906+
877907 try {
878908 verifyIsActive ();
879909 clearNamespacesInternal ();
880910 } finally {
881- updateLock . unlock ();
911+ exclusiveLock . release ();
882912 }
913+ } catch (InterruptedException e ) {
914+ Thread .currentThread ().interrupt ();
915+ throw new SailException (e );
883916 } finally {
884917 try {
885918 activeThread .setRelease (null );
0 commit comments