Use internal thread pool for update repos

This commit is contained in:
topjohnwu 2018-07-27 21:59:30 +08:00
parent 413d4badfd
commit 41c0721159

View File

@ -1,7 +1,6 @@
package com.topjohnwu.magisk.asyncs; package com.topjohnwu.magisk.asyncs;
import android.database.Cursor; import android.database.Cursor;
import android.os.AsyncTask;
import android.text.TextUtils; import android.text.TextUtils;
import com.topjohnwu.magisk.MagiskManager; import com.topjohnwu.magisk.MagiskManager;
@ -29,7 +28,9 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class UpdateRepos extends ParallelTask<Void, Void, Void> { public class UpdateRepos extends ParallelTask<Void, Void, Void> {
@ -37,47 +38,27 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
private static final int LOAD_NEXT = 1; private static final int LOAD_NEXT = 1;
private static final int LOAD_PREV = 2; private static final int LOAD_PREV = 2;
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = Math.max(2, CPU_COUNT - 1);
private MagiskManager mm; private MagiskManager mm;
private List<String> etags, newEtags = new LinkedList<>(); private List<String> etags, newEtags = new LinkedList<>();
private Set<String> cached; private Set<String> cached;
private boolean forceUpdate; private boolean forceUpdate;
private AtomicInteger taskCount = new AtomicInteger(0); private ExecutorService threadPool;
final private Object allDone = new Object();
public UpdateRepos(boolean force) { public UpdateRepos(boolean force) {
mm = MagiskManager.get(); mm = MagiskManager.get();
mm.repoLoadDone.reset(); mm.repoLoadDone.reset();
forceUpdate = force; forceUpdate = force;
} threadPool = Executors.newFixedThreadPool(CORE_POOL_SIZE);
private void queueTask(Runnable task) {
// Thread pool's queue has an upper bound, batch it with 64 tasks
while (taskCount.get() >= 64) {
waitTasks();
}
taskCount.incrementAndGet();
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
task.run();
if (taskCount.decrementAndGet() == 0) {
synchronized (allDone) {
allDone.notify();
}
}
});
} }
private void waitTasks() { private void waitTasks() {
if (taskCount.get() == 0) threadPool.shutdown();
return;
synchronized (allDone) {
try { try {
allDone.wait(); threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) { } catch (InterruptedException ignored) {}
// Wait again
waitTasks();
}
}
} }
private boolean loadJSON(String jsonString) throws JSONException, ParseException { private boolean loadJSON(String jsonString) throws JSONException, ParseException {
@ -93,7 +74,7 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
String name = rawRepo.getString("name"); String name = rawRepo.getString("name");
Date date = dateFormat.parse(rawRepo.getString("pushed_at")); Date date = dateFormat.parse(rawRepo.getString("pushed_at"));
Set<String> set = Collections.synchronizedSet(cached); Set<String> set = Collections.synchronizedSet(cached);
queueTask(() -> { threadPool.execute(() -> {
Repo repo = mm.repoDB.getRepo(id); Repo repo = mm.repoDB.getRepo(id);
try { try {
if (repo == null) if (repo == null)
@ -187,7 +168,7 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
Cursor c = mm.repoDB.getRawCursor(); Cursor c = mm.repoDB.getRawCursor();
while (c.moveToNext()) { while (c.moveToNext()) {
Repo repo = new Repo(c); Repo repo = new Repo(c);
queueTask(() -> { threadPool.execute(() -> {
try { try {
repo.update(); repo.update();
mm.repoDB.addRepo(repo); mm.repoDB.addRepo(repo);