@@ -594,6 +594,7 @@ private SQLiteConnection waitForConnection(String sql, int connectionFlags,
594594 (connectionFlags & CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY ) != 0 ;
595595
596596 final ConnectionWaiter waiter ;
597+ final int nonce ;
597598 synchronized (mLock ) {
598599 throwIfClosedLocked ();
599600
@@ -636,73 +637,75 @@ private SQLiteConnection waitForConnection(String sql, int connectionFlags,
636637 mConnectionWaiterQueue = waiter ;
637638 }
638639
639- if (cancellationSignal != null ) {
640- final int nonce = waiter .mNonce ;
641- cancellationSignal .setOnCancelListener (new CancellationSignal .OnCancelListener () {
642- @ Override
643- public void onCancel () {
644- synchronized (mLock ) {
645- cancelConnectionWaiterLocked (waiter , nonce );
640+ nonce = waiter .mNonce ;
641+ }
642+
643+ // Set up the cancellation listener.
644+ if (cancellationSignal != null ) {
645+ cancellationSignal .setOnCancelListener (new CancellationSignal .OnCancelListener () {
646+ @ Override
647+ public void onCancel () {
648+ synchronized (mLock ) {
649+ if (waiter .mNonce == nonce ) {
650+ cancelConnectionWaiterLocked (waiter );
646651 }
647652 }
648- });
649- }
653+ }
654+ });
650655 }
651-
652- // Park the thread until a connection is assigned or the pool is closed.
653- // Rethrow an exception from the wait, if we got one.
654- long busyTimeoutMillis = CONNECTION_POOL_BUSY_MILLIS ;
655- long nextBusyTimeoutTime = waiter .mStartTime + busyTimeoutMillis ;
656- for (;;) {
657- // Detect and recover from connection leaks.
658- if (mConnectionLeaked .compareAndSet (true , false )) {
659- synchronized (mLock ) {
660- wakeConnectionWaitersLocked ();
656+ try {
657+ // Park the thread until a connection is assigned or the pool is closed.
658+ // Rethrow an exception from the wait, if we got one.
659+ long busyTimeoutMillis = CONNECTION_POOL_BUSY_MILLIS ;
660+ long nextBusyTimeoutTime = waiter .mStartTime + busyTimeoutMillis ;
661+ for (;;) {
662+ // Detect and recover from connection leaks.
663+ if (mConnectionLeaked .compareAndSet (true , false )) {
664+ synchronized (mLock ) {
665+ wakeConnectionWaitersLocked ();
666+ }
661667 }
662- }
663668
664- // Wait to be unparked (may already have happened), a timeout, or interruption.
665- LockSupport .parkNanos (this , busyTimeoutMillis * 1000000L );
669+ // Wait to be unparked (may already have happened), a timeout, or interruption.
670+ LockSupport .parkNanos (this , busyTimeoutMillis * 1000000L );
666671
667- // Clear the interrupted flag, just in case.
668- Thread .interrupted ();
672+ // Clear the interrupted flag, just in case.
673+ Thread .interrupted ();
669674
670- // Check whether we are done waiting yet.
671- synchronized (mLock ) {
672- throwIfClosedLocked ();
673-
674- final SQLiteConnection connection = waiter .mAssignedConnection ;
675- final RuntimeException ex = waiter .mException ;
676- if (connection != null || ex != null ) {
677- if (cancellationSignal != null ) {
678- cancellationSignal .setOnCancelListener (null );
679- }
680- recycleConnectionWaiterLocked (waiter );
681- if (connection != null ) {
682- return connection ;
675+ // Check whether we are done waiting yet.
676+ synchronized (mLock ) {
677+ throwIfClosedLocked ();
678+
679+ final SQLiteConnection connection = waiter .mAssignedConnection ;
680+ final RuntimeException ex = waiter .mException ;
681+ if (connection != null || ex != null ) {
682+ recycleConnectionWaiterLocked (waiter );
683+ if (connection != null ) {
684+ return connection ;
685+ }
686+ throw ex ; // rethrow!
683687 }
684- throw ex ; // rethrow!
685- }
686688
687- final long now = SystemClock .uptimeMillis ();
688- if (now < nextBusyTimeoutTime ) {
689- busyTimeoutMillis = now - nextBusyTimeoutTime ;
690- } else {
691- logConnectionPoolBusyLocked (now - waiter .mStartTime , connectionFlags );
692- busyTimeoutMillis = CONNECTION_POOL_BUSY_MILLIS ;
693- nextBusyTimeoutTime = now + busyTimeoutMillis ;
689+ final long now = SystemClock .uptimeMillis ();
690+ if (now < nextBusyTimeoutTime ) {
691+ busyTimeoutMillis = now - nextBusyTimeoutTime ;
692+ } else {
693+ logConnectionPoolBusyLocked (now - waiter .mStartTime , connectionFlags );
694+ busyTimeoutMillis = CONNECTION_POOL_BUSY_MILLIS ;
695+ nextBusyTimeoutTime = now + busyTimeoutMillis ;
696+ }
694697 }
695698 }
699+ } finally {
700+ // Remove the cancellation listener.
701+ if (cancellationSignal != null ) {
702+ cancellationSignal .setOnCancelListener (null );
703+ }
696704 }
697705 }
698706
699707 // Can't throw.
700- private void cancelConnectionWaiterLocked (ConnectionWaiter waiter , int nonce ) {
701- if (waiter .mNonce != nonce ) {
702- // Waiter already removed and recycled.
703- return ;
704- }
705-
708+ private void cancelConnectionWaiterLocked (ConnectionWaiter waiter ) {
706709 if (waiter .mAssignedConnection != null || waiter .mException != null ) {
707710 // Waiter is done waiting but has not woken up yet.
708711 return ;
0 commit comments