Introduce thread priorities for threads and handlerthreads.

This commit is contained in:
Clark
2023-03-08 17:29:44 -05:00
committed by Greyson Parrelli
parent 2cef06cd6e
commit 79a062c838
22 changed files with 88 additions and 33 deletions

View File

@@ -8,6 +8,8 @@ package org.signal.glide.common.executor;
import android.os.HandlerThread;
import android.os.Looper;
import org.signal.core.util.ThreadUtil;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
@@ -39,7 +41,7 @@ public class FrameDecoderExecutor {
public Looper getLooper(int taskId) {
int idx = taskId % sPoolNumber;
if (idx >= mHandlerThreadGroup.size()) {
HandlerThread handlerThread = new HandlerThread("FrameDecoderExecutor-" + idx);
HandlerThread handlerThread = new HandlerThread("FrameDecoderExecutor-" + idx, ThreadUtil.PRIORITY_BACKGROUND_THREAD);
handlerThread.start();
mHandlerThreadGroup.add(handlerThread);

View File

@@ -7,6 +7,7 @@ import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.media.MediaRecorder;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import org.signal.core.util.StreamUtil;
import org.signal.core.util.logging.Log;
@@ -65,6 +66,7 @@ public class AudioCodec implements Recorder {
new Thread(new Runnable() {
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO);
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
byte[] audioRecordData = new byte[bufferSize];
ByteBuffer[] codecInputBuffers = mediaCodec.getInputBuffers();

View File

@@ -9,6 +9,7 @@ import android.os.ParcelFileDescriptor;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.components.voice.VoiceNoteDraft;
@@ -25,7 +26,7 @@ public class AudioRecorder {
private static final String TAG = Log.tag(AudioRecorder.class);
private static final ExecutorService executor = SignalExecutors.newCachedSingleThreadExecutor("signal-AudioRecorder");
private static final ExecutorService executor = SignalExecutors.newCachedSingleThreadExecutor("signal-AudioRecorder", ThreadUtil.PRIORITY_UI_BLOCKING_THREAD);
private final Context context;
private final AudioRecordingHandler uiHandler;

View File

@@ -9,6 +9,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import org.signal.core.util.Hex;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.concurrent.DeadlockDetector;
import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations;
@@ -137,7 +138,7 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
signalWebSocket,
Optional.of(new SecurityEventListener(context)),
provideGroupsV2Operations(signalServiceConfiguration).getProfileOperations(),
SignalExecutors.newCachedBoundedExecutor("signal-messages", 1, 16, 30),
SignalExecutors.newCachedBoundedExecutor("signal-messages", ThreadUtil.PRIORITY_IMPORTANT_BACKGROUND_THREAD, 1, 16, 30),
ByteUnit.KILOBYTES.toBytes(256),
FeatureFlags.okHttpAutomaticRetry());
}
@@ -373,7 +374,7 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
@Override
public @NonNull DeadlockDetector provideDeadlockDetector() {
HandlerThread handlerThread = new HandlerThread("signal-DeadlockDetector");
HandlerThread handlerThread = new HandlerThread("signal-DeadlockDetector", ThreadUtil.PRIORITY_BACKGROUND_THREAD);
handlerThread.start();
return new DeadlockDetector(new Handler(handlerThread.getLooper()), TimeUnit.SECONDS.toMillis(5));
}

View File

@@ -27,7 +27,7 @@ private val TAG = Log.tag(JumboEmoji::class.java)
*/
object JumboEmoji {
private val executor = ThreadUtil.trace(SignalExecutors.newCachedSingleThreadExecutor("jumbo-emoji"))
private val executor = ThreadUtil.trace(SignalExecutors.newCachedSingleThreadExecutor("jumbo-emoji", ThreadUtil.PRIORITY_IMPORTANT_BACKGROUND_THREAD))
const val MAX_JUMBOJI_COUNT = 5

View File

@@ -7,6 +7,7 @@ import androidx.annotation.NonNull;
import com.annimon.stream.Stream;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.logging.Log;
import java.util.List;
@@ -30,7 +31,7 @@ class InAppScheduler implements Scheduler {
private final Handler handler;
InAppScheduler(@NonNull JobManager jobManager) {
HandlerThread handlerThread = new HandlerThread("InAppScheduler");
HandlerThread handlerThread = new HandlerThread("InAppScheduler", ThreadUtil.PRIORITY_BACKGROUND_THREAD);
handlerThread.start();
this.jobManager = jobManager;

View File

@@ -1,7 +1,10 @@
package org.thoughtcrime.securesms.jobmanager.impl;
import android.os.Process;
import androidx.annotation.NonNull;
import org.signal.core.util.ThreadUtil;
import org.thoughtcrime.securesms.jobmanager.ExecutorFactory;
import java.util.concurrent.ExecutorService;
@@ -10,6 +13,11 @@ import java.util.concurrent.Executors;
public class DefaultExecutorFactory implements ExecutorFactory {
@Override
public @NonNull ExecutorService newSingleThreadExecutor(@NonNull String name) {
return Executors.newSingleThreadExecutor(r -> new Thread(r, name));
return Executors.newSingleThreadExecutor(r -> new Thread(r, name) {
@Override public void run() {
Process.setThreadPriority(ThreadUtil.PRIORITY_BACKGROUND_THREAD);
super.run();
}
});
}
}

View File

@@ -5,6 +5,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.util.SignalUncaughtExceptionHandler;
@@ -35,7 +36,7 @@ public final class KeyValueStore implements KeyValueReader {
private KeyValueDataSet dataSet;
public KeyValueStore(@NonNull KeyValuePersistentStorage storage) {
this.executor = SignalExecutors.newCachedSingleThreadExecutor("signal-KeyValueStore");
this.executor = SignalExecutors.newCachedSingleThreadExecutor("signal-KeyValueStore", ThreadUtil.PRIORITY_BACKGROUND_THREAD);
this.storage = storage;
}

View File

@@ -8,6 +8,7 @@ import androidx.annotation.WorkerThread;
import com.annimon.stream.Stream;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.attachments.Attachment;
@@ -56,7 +57,7 @@ public class MediaUploadRepository {
public MediaUploadRepository(@NonNull Context context) {
this.context = context;
this.uploadResults = new LinkedHashMap<>();
this.executor = SignalExecutors.newCachedSingleThreadExecutor("signal-MediaUpload");
this.executor = SignalExecutors.newCachedSingleThreadExecutor("signal-MediaUpload", ThreadUtil.PRIORITY_IMPORTANT_BACKGROUND_THREAD);
}
public void startUpload(@NonNull Media media, @Nullable Recipient recipient) {

View File

@@ -9,6 +9,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.ExceptionUtil;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.concurrent.SignalExecutors;
import org.thoughtcrime.securesms.notifications.v2.DefaultMessageNotifier;
import org.thoughtcrime.securesms.notifications.v2.ConversationId;
@@ -28,7 +29,7 @@ public class OptimizedMessageNotifier implements MessageNotifier {
@MainThread
public OptimizedMessageNotifier(@NonNull Application context) {
this.limiter = new LeakyBucketLimiter(5, 1000, new Handler(SignalExecutors.getAndStartHandlerThread("signal-notifier").getLooper()));
this.limiter = new LeakyBucketLimiter(5, 1000, new Handler(SignalExecutors.getAndStartHandlerThread("signal-notifier", ThreadUtil.PRIORITY_IMPORTANT_BACKGROUND_THREAD).getLooper()));
this.defaultMessageNotifier = new DefaultMessageNotifier(context);
}

View File

@@ -36,6 +36,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import org.signal.core.util.StreamUtil;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.BuildConfig;
@@ -201,7 +202,7 @@ public final class PartProvider extends BaseContentProvider {
@RequiresApi(26)
private ParcelFileDescriptor getParcelStreamProxyForAttachment(AttachmentId attachmentId) throws IOException {
StorageManager storageManager = Objects.requireNonNull(getContext().getSystemService(StorageManager.class));
HandlerThread thread = SignalExecutors.getAndStartHandlerThread("storageservice-proxy");
HandlerThread thread = SignalExecutors.getAndStartHandlerThread("storageservice-proxy", ThreadUtil.PRIORITY_IMPORTANT_BACKGROUND_THREAD);
Handler handler = new Handler(thread.getLooper());
ParcelFileDescriptor parcelFileDescriptor = storageManager.openProxyFileDescriptor(ParcelFileDescriptor.MODE_READ_ONLY,

View File

@@ -49,7 +49,7 @@ public final class LiveRecipientCache {
private final AtomicBoolean warmedUp;
public LiveRecipientCache(@NonNull Context context) {
this(context, ThreadUtil.trace(new FilteredExecutor(SignalExecutors.newCachedBoundedExecutor("signal-recipients", 1, 4, 15), () -> !SignalDatabase.inTransaction())));
this(context, ThreadUtil.trace(new FilteredExecutor(SignalExecutors.newCachedBoundedExecutor("signal-recipients", ThreadUtil.PRIORITY_UI_BLOCKING_THREAD, 1, 4, 15), () -> !SignalDatabase.inTransaction())));
}
@VisibleForTesting

View File

@@ -16,6 +16,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import org.signal.core.util.PendingIntentFlags;
import org.signal.core.util.ThreadUtil;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.util.ServiceUtil;
@@ -30,7 +31,7 @@ public abstract class TimedEventManager<E> {
private final Handler handler;
public TimedEventManager(@NonNull Application application, @NonNull String threadName) {
HandlerThread handlerThread = new HandlerThread(threadName);
HandlerThread handlerThread = new HandlerThread(threadName, ThreadUtil.PRIORITY_BACKGROUND_THREAD);
handlerThread.start();
this.application = application;

View File

@@ -1,5 +1,6 @@
package org.thoughtcrime.securesms.util
import org.signal.core.util.ThreadUtil
import org.signal.core.util.concurrent.SignalExecutors
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.database.LocalMetricsDatabase
@@ -29,7 +30,7 @@ object LocalMetrics {
private val eventsById: MutableMap<String, LocalMetricsEvent> = LRUCache(200)
private val lastSplitTimeById: MutableMap<String, Long> = LRUCache(200)
private val executor: Executor = SignalExecutors.newCachedSingleThreadExecutor("signal-LocalMetrics")
private val executor: Executor = SignalExecutors.newCachedSingleThreadExecutor("signal-LocalMetrics", ThreadUtil.PRIORITY_BACKGROUND_THREAD)
private val db: LocalMetricsDatabase by lazy { LocalMetricsDatabase.getInstance(ApplicationDependencies.getApplication()) }
@JvmStatic

View File

@@ -8,6 +8,7 @@ import android.media.AudioManager
import android.media.SoundPool
import android.net.Uri
import android.os.Build
import org.signal.core.util.ThreadUtil
import org.signal.core.util.concurrent.SignalExecutors
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.R
@@ -21,7 +22,7 @@ private val TAG = Log.tag(SignalAudioManager::class.java)
sealed class SignalAudioManager(protected val context: Context, protected val eventListener: EventListener?) {
private var commandAndControlThread = SignalExecutors.getAndStartHandlerThread("call-audio")
private var commandAndControlThread = SignalExecutors.getAndStartHandlerThread("call-audio", ThreadUtil.PRIORITY_IMPORTANT_BACKGROUND_THREAD)
protected val handler = SignalAudioHandler(commandAndControlThread.looper)
protected var state: State = State.UNINITIALIZED