Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c7b41ad authored by Jeff Brown's avatar Jeff Brown
Browse files

Rename Looper::isIdling() to isPolling() to resolve confusion.

The loop isn't technically idle at this time, it's just checking
whether any file descriptors have pending events.  However it's
still a good signal as to whether the loop is alive.

Added a real isIdle() function.

Bug: 19532373
Change-Id: Idd273e8774f469ccafb00d560818cf279dfd6ba6
parent 044644c7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -22369,6 +22369,7 @@ package android.os {
  public final class MessageQueue {
    method public void addIdleHandler(android.os.MessageQueue.IdleHandler);
    method public boolean isIdle();
    method public void removeIdleHandler(android.os.MessageQueue.IdleHandler);
  }
+1 −0
Original line number Diff line number Diff line
@@ -23964,6 +23964,7 @@ package android.os {
  public final class MessageQueue {
    method public void addIdleHandler(android.os.MessageQueue.IdleHandler);
    method public boolean isIdle();
    method public void removeIdleHandler(android.os.MessageQueue.IdleHandler);
  }
+4 −4
Original line number Diff line number Diff line
@@ -96,15 +96,15 @@ public class RequestHandlerThread extends HandlerThread {
    // Blocks until thread is idling
    public void waitUntilIdle() {
        Handler handler = waitAndGetHandler();
        Looper looper = handler.getLooper();
        if (looper.isIdling()) {
        MessageQueue queue = handler.getLooper().getQueue();
        if (queue.isIdle()) {
            return;
        }
        mIdle.close();
        looper.getQueue().addIdleHandler(mIdleHandler);
        queue.addIdleHandler(mIdleHandler);
        // Ensure that the idle handler gets run even if the looper already went idle
        handler.sendEmptyMessage(MSG_POKE_IDLE_HANDLER);
        if (looper.isIdling()) {
        if (queue.isIdle()) {
            return;
        }
        mIdle.block();
+10 −10
Original line number Diff line number Diff line
@@ -50,6 +50,16 @@ import android.util.Printer;
  *  }</pre>
  */
public final class Looper {
    /*
     * API Implementation Note:
     *
     * This class contains the code required to set up and manage an event loop
     * based on MessageQueue.  APIs that affect the state of the queue should be
     * defined on MessageQueue or Handler rather than on Looper itself.  For example,
     * idle handlers and sync barriers are defined on the queue whereas preparing the
     * thread, looping and quitting are defined on the looper.
     */

    private static final String TAG = "Looper";

    // sThreadLocal.get() will return null unless you've called prepare().
@@ -286,16 +296,6 @@ public final class Looper {
        return mQueue;
    }

    /**
     * Return whether this looper's thread is currently idle, waiting for new work
     * to do.  This is intrinsically racy, since its state can change before you get
     * the result back.
     * @hide
     */
    public boolean isIdling() {
        return mQueue.isIdling();
    }

    public void dump(Printer pw, String prefix) {
        pw.println(prefix + toString());
        mQueue.dump(pw, prefix + "  ");
+73 −46
Original line number Diff line number Diff line
@@ -52,21 +52,43 @@ public final class MessageQueue {
    private native static void nativeDestroy(long ptr);
    private native static void nativePollOnce(long ptr, int timeoutMillis);
    private native static void nativeWake(long ptr);
    private native static boolean nativeIsIdling(long ptr);
    private native static boolean nativeIsPolling(long ptr);

    MessageQueue(boolean quitAllowed) {
        mQuitAllowed = quitAllowed;
        mPtr = nativeInit();
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            dispose();
        } finally {
            super.finalize();
        }
    }

    // Disposes of the underlying message queue.
    // Must only be called on the looper thread or the finalizer.
    private void dispose() {
        if (mPtr != 0) {
            nativeDestroy(mPtr);
            mPtr = 0;
        }
    }

    /**
     * Callback interface for discovering when a thread is going to block
     * waiting for more messages.
     */
    public static interface IdleHandler {
        /**
         * Called when the message queue has run out of messages and will now
         * wait for more.  Return true to keep your idle handler active, false
         * to have it removed.  This may be called if there are still messages
         * pending in the queue, but they are all scheduled to be dispatched
         * after the current time.
     * Returns true if the looper has no pending messages which are due to be processed.
     *
     * <p>This method is safe to call from any thread.
     *
     * @return True if the looper is idle.
     */
        boolean queueIdle();
    public boolean isIdle() {
        synchronized (this) {
            final long now = SystemClock.uptimeMillis();
            return mMessages == null || now < mMessages.when;
        }
    }

    /**
@@ -93,6 +115,8 @@ public final class MessageQueue {
     * with {@link #addIdleHandler}.  If the given object is not currently
     * in the idle list, nothing is done.
     *
     * <p>This method is safe to call from any thread.
     *
     * @param handler The IdleHandler to be removed.
     */
    public void removeIdleHandler(IdleHandler handler) {
@@ -101,27 +125,27 @@ public final class MessageQueue {
        }
    }

    MessageQueue(boolean quitAllowed) {
        mQuitAllowed = quitAllowed;
        mPtr = nativeInit();
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            dispose();
        } finally {
            super.finalize();
    /**
     * Returns whether this looper's thread is currently polling for more work to do.
     * This is a good signal that the loop is still alive rather than being stuck
     * handling a callback.  Note that this method is intrinsically racy, since the
     * state of the loop can change before you get the result back.
     *
     * <p>This method is safe to call from any thread.
     *
     * @return True if the looper is currently polling for events.
     * @hide
     */
    public boolean isPolling() {
        synchronized (this) {
            return isPollingLocked();
        }
    }

    // Disposes of the underlying message queue.
    // Must only be called on the looper thread or the finalizer.
    private void dispose() {
        if (mPtr != 0) {
            nativeDestroy(mPtr);
            mPtr = 0;
        }
    private boolean isPollingLocked() {
        // If the loop is quitting then it must not be idling.
        // We can assume mPtr != 0 when mQuitting is false.
        return !mQuitting && nativeIsPolling(mPtr);
    }

    Message next() {
@@ -400,18 +424,6 @@ public final class MessageQueue {
        }
    }

    boolean isIdling() {
        synchronized (this) {
            return isIdlingLocked();
        }
    }

    private boolean isIdlingLocked() {
        // If the loop is quitting then it must not be idling.
        // We can assume mPtr != 0 when mQuitting is false.
        return !mQuitting && nativeIsIdling(mPtr);
     }

    void removeMessages(Handler h, int what, Object object) {
        if (h == null) {
            return;
@@ -559,8 +571,23 @@ public final class MessageQueue {
                pw.println(prefix + "Message " + n + ": " + msg.toString(now));
                n++;
            }
            pw.println(prefix + "(Total messages: " + n + ", idling=" + isIdlingLocked()
            pw.println(prefix + "(Total messages: " + n + ", polling=" + isPollingLocked()
                    + ", quitting=" + mQuitting + ")");
        }
    }

    /**
     * Callback interface for discovering when a thread is going to block
     * waiting for more messages.
     */
    public static interface IdleHandler {
        /**
         * Called when the message queue has run out of messages and will now
         * wait for more.  Return true to keep your idle handler active, false
         * to have it removed.  This may be called if there are still messages
         * pending in the queue, but they are all scheduled to be dispatched
         * after the current time.
         */
        boolean queueIdle();
    }
}
Loading