Loading core/java/android/app/SystemServiceRegistry.java +18 −5 Original line number Diff line number Diff line Loading @@ -1658,6 +1658,9 @@ public final class SystemServiceRegistry { public final T getService(ContextImpl ctx) { final Object[] cache = ctx.mServiceCache; final int[] gates = ctx.mServiceInitializationStateArray; boolean interrupted = false; T ret = null; for (;;) { boolean doInitialize = false; Loading @@ -1665,7 +1668,8 @@ public final class SystemServiceRegistry { // Return it if we already have a cached instance. T service = (T) cache[mCacheIndex]; if (service != null || gates[mCacheIndex] == ContextImpl.STATE_NOT_FOUND) { return service; ret = service; break; // exit the for (;;) } // If we get here, there's no cached instance. Loading Loading @@ -1708,24 +1712,33 @@ public final class SystemServiceRegistry { cache.notifyAll(); } } return service; ret = service; break; // exit the for (;;) } // The other threads will wait for the first thread to call notifyAll(), // and go back to the top and retry. synchronized (cache) { // Repeat until the state becomes STATE_READY or STATE_NOT_FOUND. // We can't respond to interrupts here; just like we can't in the "doInitialize" // path, so we remember the interrupt state here and re-interrupt later. while (gates[mCacheIndex] < ContextImpl.STATE_READY) { try { // Clear the interrupt state. interrupted |= Thread.interrupted(); cache.wait(); } catch (InterruptedException e) { // This shouldn't normally happen, but if someone interrupts the // thread, it will. Slog.wtf(TAG, "getService() interrupted"); Thread.currentThread().interrupt(); return null; Slog.w(TAG, "getService() interrupted"); interrupted = true; } } } } if (interrupted) { Thread.currentThread().interrupt(); } return ret; } public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException; Loading Loading
core/java/android/app/SystemServiceRegistry.java +18 −5 Original line number Diff line number Diff line Loading @@ -1658,6 +1658,9 @@ public final class SystemServiceRegistry { public final T getService(ContextImpl ctx) { final Object[] cache = ctx.mServiceCache; final int[] gates = ctx.mServiceInitializationStateArray; boolean interrupted = false; T ret = null; for (;;) { boolean doInitialize = false; Loading @@ -1665,7 +1668,8 @@ public final class SystemServiceRegistry { // Return it if we already have a cached instance. T service = (T) cache[mCacheIndex]; if (service != null || gates[mCacheIndex] == ContextImpl.STATE_NOT_FOUND) { return service; ret = service; break; // exit the for (;;) } // If we get here, there's no cached instance. Loading Loading @@ -1708,24 +1712,33 @@ public final class SystemServiceRegistry { cache.notifyAll(); } } return service; ret = service; break; // exit the for (;;) } // The other threads will wait for the first thread to call notifyAll(), // and go back to the top and retry. synchronized (cache) { // Repeat until the state becomes STATE_READY or STATE_NOT_FOUND. // We can't respond to interrupts here; just like we can't in the "doInitialize" // path, so we remember the interrupt state here and re-interrupt later. while (gates[mCacheIndex] < ContextImpl.STATE_READY) { try { // Clear the interrupt state. interrupted |= Thread.interrupted(); cache.wait(); } catch (InterruptedException e) { // This shouldn't normally happen, but if someone interrupts the // thread, it will. Slog.wtf(TAG, "getService() interrupted"); Thread.currentThread().interrupt(); return null; Slog.w(TAG, "getService() interrupted"); interrupted = true; } } } } if (interrupted) { Thread.currentThread().interrupt(); } return ret; } public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException; Loading