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

Commit 80a05232 authored by Marco Ballesio's avatar Marco Ballesio
Browse files

ActivityManager: don't freeze processes holding file locks

As a temporary measure waiting for the more robust b/176927978 to be
implemented, query the file lock status of processes prior freezing
them, and skip freeze if any locks are held.

Test: verified form the logs that processes holding file locks are not
frozen
Bug: 176928302

Change-Id: Ib7e1715effb63c1b304ce22a9451294fd9f7b10d
Merged-In: Ib7e1715effb63c1b304ce22a9451294fd9f7b10d
parent 2dd4e12e
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -31,8 +31,12 @@ import dalvik.system.VMRuntime;

import libcore.io.IoUtils;

import java.io.BufferedReader;
import java.io.FileDescriptor;
import java.io.FileReader;
import java.io.IOException;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.TimeoutException;

/**
@@ -1393,4 +1397,38 @@ public class Process {
    }

    private static native int nativePidFdOpen(int pid, int flags) throws ErrnoException;

    /**
     * Checks if a process corresponding to a specific pid owns any file locks.
     * @param pid The process ID for which we want to know the existence of file locks.
     * @return true If the process holds any file locks, false otherwise.
     * @throws IOException if /proc/locks can't be accessed.
     *
     * @hide
     */
    public static boolean hasFileLocks(int pid) throws IOException {
        BufferedReader br = null;

        try {
            br = new BufferedReader(new FileReader("/proc/locks"));
            String line;

            while ((line = br.readLine()) != null) {
                StringTokenizer st = new StringTokenizer(line);

                for (int i = 0; i < 5 && st.hasMoreTokens(); i++) {
                    String str = st.nextToken();
                    if (i == 4 && Integer.parseInt(str) == pid) {
                        return true;
                    }
                }
            }

            return false;
        } finally {
            if (br != null) {
                br.close();
            }
        }
    }
}
+57 −25
Original line number Diff line number Diff line
@@ -1101,15 +1101,26 @@ public final class CachedAppOptimizer {
        }

        private void freezeProcess(ProcessRecord proc) {
            final int pid;
            final String name;
            final int pid = proc.pid;
            final String name = proc.processName;
            final long unfrozenDuration;
            final boolean frozen;

            synchronized (mAm) {
                pid = proc.pid;
                name = proc.processName;
            try {
                // pre-check for locks to avoid unnecessary freeze/unfreeze operations
                if (Process.hasFileLocks(pid)) {
                    if (DEBUG_FREEZER) {
                        Slog.d(TAG_AM, name + " (" + pid + ") holds file locks, not freezing");
                    }
                    return;
                }
            } catch (IOException e) {
                Slog.e(TAG_AM, "Not freezing. Unable to check file locks for " + name + "(" + pid
                        + "): " + e);
                return;
            }

            synchronized (mAm) {
                if (proc.curAdj < ProcessList.CACHED_APP_MIN_ADJ
                        || proc.shouldNotFreeze) {
                    if (DEBUG_FREEZER) {
@@ -1141,7 +1152,11 @@ public final class CachedAppOptimizer {
                frozen = proc.frozen;
            }

            if (frozen) {
            if (!frozen) {
                return;
            }


            if (DEBUG_FREEZER) {
                Slog.d(TAG_AM, "froze " + pid + " " + name);
            }
@@ -1165,6 +1180,23 @@ public final class CachedAppOptimizer {
                        name,
                        unfrozenDuration);
            }

            try {
                // post-check to prevent races
                if (Process.hasFileLocks(pid)) {
                    if (DEBUG_FREEZER) {
                        Slog.d(TAG_AM, name + " (" + pid + ") holds file locks, reverting freeze");
                    }

                    synchronized (mAm) {
                        unfreezeAppLocked(proc);
                    }
                }
            } catch (IOException e) {
                Slog.e(TAG_AM, "Unable to check file locks for " + name + "(" + pid + "): " + e);
                synchronized (mAm) {
                    unfreezeAppLocked(proc);
                }
            }
        }