Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package java.lang;
import android.compat.annotation.UnsupportedAppUsage;
import android.system.Os;
import android.system.OsConstants;
import java.lang.ref.FinalizerReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import libcore.util.EmptyArray;
import dalvik.system.VMRuntime;
import dalvik.system.VMDebug;
/**
* Calls Object.finalize() on objects in the finalizer reference queue. The VM
* will abort if any finalize() call takes more than the maximum finalize time
* to complete.
*
* @hide
*/
public final class Daemons {
private static final int NANOS_PER_MILLI = 1000 * 1000;
// This used to be final. IT IS NOW ONLY WRITTEN. We now update it when we look at the command
// line argument, for the benefit of mis-behaved apps that might read it. SLATED FOR REMOVAL.
// There is no reason to use this: Finalizers should not rely on the value. If a finalizer takes
// appreciable time, the work should be done elsewhere. Based on disassembly of Daemons.class,
// the value is effectively inlined, so changing the field never did have an effect.
// DO NOT USE. FOR ANYTHING. THIS WILL BE REMOVED SHORTLY.
@UnsupportedAppUsage
private static long MAX_FINALIZE_NANOS = 10L * 1000 * NANOS_PER_MILLI;
private static final Daemon[] DAEMONS = new Daemon[] {
HeapTaskDaemon.INSTANCE,
ReferenceQueueDaemon.INSTANCE,
FinalizerDaemon.INSTANCE,
FinalizerWatchdogDaemon.INSTANCE,
};
private static final CountDownLatch POST_ZYGOTE_START_LATCH = new CountDownLatch(DAEMONS.length);
private static final CountDownLatch PRE_ZYGOTE_START_LATCH = new CountDownLatch(DAEMONS.length);
private static boolean postZygoteFork = false;
@UnsupportedAppUsage
public static void start() {
for (Daemon daemon : DAEMONS) {
daemon.start();
}
}
public static void startPostZygoteFork() {
postZygoteFork = true;
for (Daemon daemon : DAEMONS) {
daemon.startPostZygoteFork();
}
}
@UnsupportedAppUsage
public static void stop() {
for (Daemon daemon : DAEMONS) {
daemon.stop();
}
}
private static void waitForDaemonStart() throws Exception {
if (postZygoteFork) {
POST_ZYGOTE_START_LATCH.await();
} else {
PRE_ZYGOTE_START_LATCH.await();
}
}
/**
* A background task that provides runtime support to the application.
* Daemons can be stopped and started, but only so that the zygote can be a
* single-threaded process when it forks.
*/
private static abstract class Daemon implements Runnable {
@UnsupportedAppUsage
private Thread thread;
private String name;
private boolean postZygoteFork;
protected Daemon(String name) {
this.name = name;
}
@UnsupportedAppUsage
public synchronized void start() {
startInternal();
}
public synchronized void startPostZygoteFork() {
postZygoteFork = true;
startInternal();
}
public void startInternal() {
if (thread != null) {
throw new IllegalStateException("already running");
}
thread = new Thread(ThreadGroup.systemThreadGroup, this, name);
thread.setDaemon(true);
thread.setSystemDaemon(true);
thread.start();
}
public final void run() {
if (postZygoteFork) {
// We don't set the priority before the Thread.start() call above because
// Thread.start() will call SetNativePriority and overwrite the desired native
// priority. We (may) use a native priority that doesn't have a corresponding
// java.lang.Thread-level priority (native priorities are more coarse-grained.)
VMRuntime.getRuntime().setSystemDaemonThreadPriority();
POST_ZYGOTE_START_LATCH.countDown();
} else {
PRE_ZYGOTE_START_LATCH.countDown();
}
runInternal();
}
public abstract void runInternal();
/**
* Returns true while the current thread should continue to run; false
* when it should return.
*/
@UnsupportedAppUsage
protected synchronized boolean isRunning() {
return thread != null;
}
public synchronized void interrupt() {
interrupt(thread);
}
public synchronized void interrupt(Thread thread) {
if (thread == null) {
throw new IllegalStateException("not running");
}
thread.interrupt();
}
/**
* Waits for the runtime thread to stop. This interrupts the thread
* currently running the runnable and then waits for it to exit.
*/
@UnsupportedAppUsage
public void stop() {
Thread threadToStop;
synchronized (this) {
threadToStop = thread;
thread = null;
}
if (threadToStop == null) {
throw new IllegalStateException("not running");
}
interrupt(threadToStop);
while (true) {
try {
threadToStop.join();
return;
} catch (InterruptedException ignored) {
} catch (OutOfMemoryError ignored) {
// An OOME may be thrown if allocating the InterruptedException failed.
}
}
}
/**
* Returns the current stack trace of the thread, or an empty stack trace
* if the thread is not currently running.
*/
public synchronized StackTraceElement[] getStackTrace() {
return thread != null ? thread.getStackTrace() : EmptyArray.STACK_TRACE_ELEMENT;
}
}
/**
* This heap management thread moves elements from the garbage collector's
* pending list to the managed reference queue.
*/
private static class ReferenceQueueDaemon extends Daemon {
@UnsupportedAppUsage
private static final ReferenceQueueDaemon INSTANCE = new ReferenceQueueDaemon();
ReferenceQueueDaemon() {
super("ReferenceQueueDaemon");
}
@Override public void runInternal() {
while (isRunning()) {
Reference> list;
try {
synchronized (ReferenceQueue.class) {
while (ReferenceQueue.unenqueued == null) {
ReferenceQueue.class.wait();
}
list = ReferenceQueue.unenqueued;
ReferenceQueue.unenqueued = null;
}
} catch (InterruptedException e) {
continue;
} catch (OutOfMemoryError e) {
continue;
}
ReferenceQueue.enqueuePending(list);
}
}
}
private static class FinalizerDaemon extends Daemon {
@UnsupportedAppUsage
private static final FinalizerDaemon INSTANCE = new FinalizerDaemon();
private final ReferenceQueue