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

Commit 11641527 authored by John Michelau's avatar John Michelau
Browse files

Fix Watchdog HeartbeatHandler to run on correct thread

The HeartbeatHandler for the System Server Watchdog has been running
on the wrong thread due to a race condition in initialization.  It's
designed to run on ServerThread, so that it can catch lockups in the
main looper of the System Server.  It has been running on
ActivityManagerThread instead, so it does not detect lockups on the
ServerThread as it should.

ActivityManagerService is calling Watchdog.getInstance() before
ServerThread calls Watchdog.getInstance().init(), so the handler is
being bound to the ActivityManagerThread instead of the ServerThread.

Explicitly bind HeartbeatHandler to ServerThread, so that the Watchdog
catches lockups on this critical thread.

Change-Id: Iccb184ac3adb817feb86ed4ee0e50e443bf74636
parent ebebb80b
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Debug;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.ServiceManager;
@@ -114,6 +115,10 @@ public class Watchdog extends Thread {
     * Used for scheduling monitor callbacks and checking memory usage.
     */
    final class HeartbeatHandler extends Handler {
        HeartbeatHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
@@ -183,7 +188,9 @@ public class Watchdog extends Thread {

    private Watchdog() {
        super("watchdog");
        mHandler = new HeartbeatHandler();
        // Explicitly bind the HeartbeatHandler to run on the ServerThread, so
        // that it can't get accidentally bound to another thread.
        mHandler = new HeartbeatHandler(Looper.getMainLooper());
    }

    public void init(Context context, BatteryService battery,