SerialSingleThreadExecutor.java

 1package eu.siacs.conversations.utils;
 2
 3import android.os.Looper;
 4import android.util.Log;
 5
 6import java.util.ArrayDeque;
 7import java.util.Queue;
 8import java.util.concurrent.Executor;
 9import java.util.concurrent.Executors;
10
11import eu.siacs.conversations.Config;
12import eu.siacs.conversations.services.AttachFileToConversationRunnable;
13
14public class SerialSingleThreadExecutor implements Executor {
15
16	private final Executor executor = Executors.newSingleThreadExecutor();
17	final ArrayDeque<Runnable> tasks = new ArrayDeque<>();
18	private Runnable active;
19	private final String name;
20
21	public SerialSingleThreadExecutor(String name) {
22		this(name, false);
23	}
24
25	SerialSingleThreadExecutor(String name, boolean prepareLooper) {
26		if (prepareLooper) {
27			execute(Looper::prepare);
28		}
29		this.name = name;
30	}
31
32	public synchronized void execute(final Runnable r) {
33		tasks.offer(() -> {
34			try {
35				r.run();
36			} finally {
37				scheduleNext();
38			}
39		});
40		if (active == null) {
41			scheduleNext();
42		}
43	}
44
45	private synchronized void scheduleNext() {
46		if ((active =  tasks.poll()) != null) {
47			executor.execute(active);
48			int remaining = tasks.size();
49			if (remaining > 0) {
50				Log.d(Config.LOGTAG,remaining+" remaining tasks on executor '"+name+"'");
51			}
52		}
53	}
54}