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}