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	final Executor executor = Executors.newSingleThreadExecutor();
17	protected 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	public SerialSingleThreadExecutor(String name, boolean prepareLooper) {
26		if (prepareLooper) {
27			execute(new Runnable() {
28				@Override
29				public void run() {
30					Looper.prepare();
31				}
32			});
33		}
34		this.name = name;
35	}
36
37	public synchronized void execute(final Runnable r) {
38		tasks.offer(new Runnable() {
39			public void run() {
40				try {
41					r.run();
42				} finally {
43					scheduleNext();
44				}
45			}
46		});
47		if (active == null) {
48			scheduleNext();
49		}
50	}
51
52	protected synchronized void scheduleNext() {
53		if ((active =  tasks.poll()) != null) {
54			executor.execute(active);
55			int remaining = tasks.size();
56			if (remaining > 0) {
57				Log.d(Config.LOGTAG,remaining+" remaining tasks on executor '"+name+"'");
58			}
59		}
60	}
61}