made i/o and memory intensive operations execute in serial order

This commit is contained in:
Daniel Gultsch 2015-06-05 08:46:06 +02:00
parent 31deb44780
commit 9d1e8205a2
2 changed files with 52 additions and 11 deletions

View file

@ -77,6 +77,7 @@ import eu.siacs.conversations.utils.ExceptionHelper;
import eu.siacs.conversations.utils.OnPhoneContactsLoadedListener; import eu.siacs.conversations.utils.OnPhoneContactsLoadedListener;
import eu.siacs.conversations.utils.PRNGFixes; import eu.siacs.conversations.utils.PRNGFixes;
import eu.siacs.conversations.utils.PhoneHelper; import eu.siacs.conversations.utils.PhoneHelper;
import eu.siacs.conversations.utils.SerialSingleThreadExecutor;
import eu.siacs.conversations.utils.Xmlns; import eu.siacs.conversations.utils.Xmlns;
import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnBindListener; import eu.siacs.conversations.xmpp.OnBindListener;
@ -119,6 +120,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
startService(intent); startService(intent);
} }
}; };
private final SerialSingleThreadExecutor mFileAddingExecutor = new SerialSingleThreadExecutor();
private final SerialSingleThreadExecutor mDatabaseExecutor = new SerialSingleThreadExecutor();
private final IBinder mBinder = new XmppConnectionBinder(); private final IBinder mBinder = new XmppConnectionBinder();
private final List<Conversation> conversations = new CopyOnWriteArrayList<>(); private final List<Conversation> conversations = new CopyOnWriteArrayList<>();
private final FileObserver fileObserver = new FileObserver( private final FileObserver fileObserver = new FileObserver(
@ -373,7 +378,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
callback.success(message); callback.success(message);
} }
} else { } else {
new Thread(new Runnable() { mFileAddingExecutor.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
@ -388,8 +393,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
callback.error(e.getResId(),message); callback.error(e.getResId(),message);
} }
} }
}).start(); });
} }
} }
@ -405,7 +409,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} }
message.setCounterpart(conversation.getNextCounterpart()); message.setCounterpart(conversation.getNextCounterpart());
message.setType(Message.TYPE_IMAGE); message.setType(Message.TYPE_IMAGE);
new Thread(new Runnable() { mFileAddingExecutor.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -420,7 +424,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
callback.error(e.getResId(), message); callback.error(e.getResId(), message);
} }
} }
}).start(); });
} }
public Conversation find(Bookmark bookmark) { public Conversation find(Bookmark bookmark) {
@ -976,7 +980,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
Account account = accountLookupTable.get(conversation.getAccountUuid()); Account account = accountLookupTable.get(conversation.getAccountUuid());
conversation.setAccount(account); conversation.setAccount(account);
} }
new Thread(new Runnable() { Runnable runnable =new Runnable() {
@Override @Override
public void run() { public void run() {
Log.d(Config.LOGTAG,"restoring roster"); Log.d(Config.LOGTAG,"restoring roster");
@ -997,7 +1001,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
Log.d(Config.LOGTAG,"restored all messages"); Log.d(Config.LOGTAG,"restored all messages");
updateConversationUi(); updateConversationUi();
} }
}).start(); };
mDatabaseExecutor.execute(runnable);
} }
} }
@ -1066,7 +1071,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation,callback)) { if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation,callback)) {
return; return;
} }
new Thread(new Runnable() { Runnable runnable = new Runnable() {
@Override @Override
public void run() { public void run() {
final Account account = conversation.getAccount(); final Account account = conversation.getAccount();
@ -1085,7 +1090,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
callback.informUser(R.string.fetching_history_from_server); callback.informUser(R.string.fetching_history_from_server);
} }
} }
}).start(); };
mDatabaseExecutor.execute(runnable);
} }
public List<Account> getAccounts() { public List<Account> getAccounts() {
@ -2344,13 +2350,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} }
public void syncRosterToDisk(final Account account) { public void syncRosterToDisk(final Account account) {
new Thread(new Runnable() { Runnable runnable = new Runnable() {
@Override @Override
public void run() { public void run() {
databaseBackend.writeRoster(account.getRoster()); databaseBackend.writeRoster(account.getRoster());
} }
}).start(); };
mDatabaseExecutor.execute(runnable);
} }

View file

@ -0,0 +1,34 @@
package eu.siacs.conversations.utils;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class SerialSingleThreadExecutor implements Executor {
final Executor executor = Executors.newSingleThreadExecutor();
final Queue<Runnable> tasks = new ArrayDeque();
Runnable active;
public synchronized void execute(final Runnable r) {
tasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (active == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((active = tasks.poll()) != null) {
executor.execute(active);
}
}
}