@@ -1815,7 +1815,9 @@ public CacheHelper getReaderCacheHelper() {
18151815 public void close (String reason , boolean flushEngine , Executor closeExecutor , ActionListener <Void > closeListener ) throws IOException {
18161816 assert assertNoEngineResetLock ();
18171817 synchronized (engineMutex ) {
1818- engineResetLock .readLock ().lock (); // prevent engine resets while closing
1818+ // The engineMutex prevents any other engine changes (like reseting the engine) to run concurrently, so we acquire the engine
1819+ // read lock here just to respect the lock ordering (engineMutex -> engineResetLock -> mutex).
1820+ engineResetLock .readLock ().lock ();
18191821 try {
18201822 try {
18211823 synchronized (mutex ) {
@@ -1981,12 +1983,7 @@ private void doLocalRecovery(
19811983 assert Thread .holdsLock (mutex ) == false : "must not hold the mutex here" ;
19821984 assert assertNoEngineResetLock ();
19831985 synchronized (engineMutex ) {
1984- engineResetLock .readLock ().lock (); // prevent engine resets while closing
1985- try {
1986- IOUtils .close (getAndSetCurrentEngine (null ));
1987- } finally {
1988- engineResetLock .readLock ().unlock ();
1989- }
1986+ IOUtils .close (getAndSetCurrentEngine (null ));
19901987 }
19911988 }, (recoveryCompleteListener , ignoredRef ) -> {
19921989 assert Thread .holdsLock (mutex ) == false : "must not hold the mutex here" ;
@@ -4509,62 +4506,57 @@ assert getActiveOperationsCount() == OPERATIONS_BLOCKED
45094506 assert globalCheckpoint == getLastSyncedGlobalCheckpoint ();
45104507 synchronized (engineMutex ) {
45114508 verifyNotClosed ();
4512- engineResetLock .readLock ().lock (); // prevent engine resets during rollback
4513- try {
4514- // we must create both new read-only engine and new read-write engine under engineMutex to ensure snapshotStoreMetadata,
4515- // acquireXXXCommit and close works.
4516- final Engine readOnlyEngine = new ReadOnlyEngine (
4517- newEngineConfig (replicationTracker ),
4518- seqNoStats ,
4519- translogStats ,
4520- false ,
4521- Function .identity (),
4522- true ,
4523- false
4524- ) {
4525- @ Override
4526- public IndexCommitRef acquireLastIndexCommit (boolean flushFirst ) {
4527- assert assertNoEngineResetLock ();
4528- synchronized (engineMutex ) {
4529- if (newEngineReference .get () == null ) {
4530- throw new AlreadyClosedException ("engine was closed" );
4531- }
4532- // ignore flushFirst since we flushed above and we do not want to interfere with ongoing translog replay
4533- return newEngineReference .get ().acquireLastIndexCommit (false );
4509+ // we must create both new read-only engine and new read-write engine under engineMutex to ensure snapshotStoreMetadata,
4510+ // acquireXXXCommit and close works.
4511+ final Engine readOnlyEngine = new ReadOnlyEngine (
4512+ newEngineConfig (replicationTracker ),
4513+ seqNoStats ,
4514+ translogStats ,
4515+ false ,
4516+ Function .identity (),
4517+ true ,
4518+ false
4519+ ) {
4520+ @ Override
4521+ public IndexCommitRef acquireLastIndexCommit (boolean flushFirst ) {
4522+ assert assertNoEngineResetLock ();
4523+ synchronized (engineMutex ) {
4524+ if (newEngineReference .get () == null ) {
4525+ throw new AlreadyClosedException ("engine was closed" );
45344526 }
4527+ // ignore flushFirst since we flushed above and we do not want to interfere with ongoing translog replay
4528+ return newEngineReference .get ().acquireLastIndexCommit (false );
45354529 }
4530+ }
45364531
4537- @ Override
4538- public IndexCommitRef acquireSafeIndexCommit () {
4539- assert assertNoEngineResetLock ();
4540- synchronized (engineMutex ) {
4541- if (newEngineReference .get () == null ) {
4542- throw new AlreadyClosedException ("engine was closed" );
4543- }
4544- return newEngineReference .get ().acquireSafeIndexCommit ();
4532+ @ Override
4533+ public IndexCommitRef acquireSafeIndexCommit () {
4534+ assert assertNoEngineResetLock ();
4535+ synchronized (engineMutex ) {
4536+ if (newEngineReference .get () == null ) {
4537+ throw new AlreadyClosedException ("engine was closed" );
45454538 }
4539+ return newEngineReference .get ().acquireSafeIndexCommit ();
45464540 }
4541+ }
45474542
4548- @ Override
4549- public void close () throws IOException {
4550- Engine newEngine ;
4551- assert assertNoEngineResetLock ();
4552- synchronized (engineMutex ) {
4553- newEngine = newEngineReference .get ();
4554- if (newEngine == getCurrentEngine (true )) {
4555- // we successfully installed the new engine so do not close it.
4556- newEngine = null ;
4557- }
4543+ @ Override
4544+ public void close () throws IOException {
4545+ Engine newEngine ;
4546+ assert assertNoEngineResetLock ();
4547+ synchronized (engineMutex ) {
4548+ newEngine = newEngineReference .get ();
4549+ if (newEngine == getCurrentEngine (true )) {
4550+ // we successfully installed the new engine so do not close it.
4551+ newEngine = null ;
45584552 }
4559- IOUtils .close (super ::close , newEngine );
45604553 }
4561- };
4562- IOUtils .close (getAndSetCurrentEngine (readOnlyEngine ));
4563- newEngineReference .set (engineFactory .newReadWriteEngine (newEngineConfig (replicationTracker )));
4564- onNewEngine (newEngineReference .get ());
4565- } finally {
4566- engineResetLock .readLock ().unlock ();
4567- }
4554+ IOUtils .close (super ::close , newEngine );
4555+ }
4556+ };
4557+ IOUtils .close (getAndSetCurrentEngine (readOnlyEngine ));
4558+ newEngineReference .set (engineFactory .newReadWriteEngine (newEngineConfig (replicationTracker )));
4559+ onNewEngine (newEngineReference .get ());
45684560 }
45694561 final Engine .TranslogRecoveryRunner translogRunner = (engine , snapshot ) -> runTranslogRecovery (
45704562 engine ,
0 commit comments