wait for threads being executed once

This commit is contained in:
B. Petersen
2019-11-09 00:40:45 +01:00
parent b16a1b6daa
commit d3af3f437b
2 changed files with 29 additions and 87 deletions
@@ -291,26 +291,22 @@ public class ApplicationDcContext extends DcContext {
**********************************************************************************************/
private final Object threadsCritical = new Object();
private final Object incLoopsCritical= new Object();
private boolean imapThreadStartedVal;
private final Object imapThreadStartedCond = new Object();
public Thread imapThread = null;
private PowerManager.WakeLock imapWakeLock = null;
private int inboxLoops = 0;
private boolean mvboxThreadStartedVal;
private final Object mvboxThreadStartedCond = new Object();
public Thread mvboxThread = null;
private PowerManager.WakeLock mvboxWakeLock = null;
private int mvboxLoops = 0;
private boolean sentboxThreadStartedVal;
private final Object sentboxThreadStartedCond = new Object();
public Thread sentboxThread = null;
private PowerManager.WakeLock sentboxWakeLock = null;
private boolean smtpThreadStartedVal;
private final Object smtpThreadStartedCond = new Object();
public Thread smtpThread = null;
private PowerManager.WakeLock smtpWakeLock = null;
private int smtpLoops = 0;
public PowerManager.WakeLock afterForegroundWakeLock = null;
@@ -321,28 +317,16 @@ public class ApplicationDcContext extends DcContext {
if (imapThread == null || !imapThread.isAlive()) {
synchronized (imapThreadStartedCond) {
imapThreadStartedVal = false;
}
imapThread = new Thread(() -> {
// raise the starting condition
// after acquiring a wakelock so that the process is not terminated.
// as imapWakeLock is not reference counted that would result in a wakelock-gap is not needed here.
imapWakeLock.acquire();
synchronized (imapThreadStartedCond) {
imapThreadStartedVal = true;
imapThreadStartedCond.notifyAll();
}
Log.i(TAG, "###################### IMAP-Thread started. ######################");
while (true) {
imapWakeLock.acquire();
performImapJobs();
performImapFetch();
imapWakeLock.release();
synchronized (incLoopsCritical) {
inboxLoops++;
}
performImapIdle();
}
}, "imapThread");
@@ -357,25 +341,16 @@ public class ApplicationDcContext extends DcContext {
if (mvboxThread == null || !mvboxThread.isAlive()) {
synchronized (mvboxThreadStartedCond) {
mvboxThreadStartedVal = false;
}
mvboxThread = new Thread(() -> {
mvboxWakeLock.acquire();
synchronized (mvboxThreadStartedCond) {
mvboxThreadStartedVal = true;
mvboxThreadStartedCond.notifyAll();
}
Log.i(TAG, "###################### MVBOX-Thread started. ######################");
while (true) {
mvboxWakeLock.acquire();
performMvboxJobs();
performMvboxFetch();
mvboxWakeLock.release();
synchronized (incLoopsCritical) {
mvboxLoops++;
}
performMvboxIdle();
}
}, "mvboxThread");
@@ -390,20 +365,8 @@ public class ApplicationDcContext extends DcContext {
if (sentboxThread == null || !sentboxThread.isAlive()) {
synchronized (sentboxThreadStartedCond) {
sentboxThreadStartedVal = false;
}
sentboxThread = new Thread(() -> {
sentboxWakeLock.acquire();
synchronized (sentboxThreadStartedCond) {
sentboxThreadStartedVal = true;
sentboxThreadStartedCond.notifyAll();
}
Log.i(TAG, "###################### SENTBOX-Thread started. ######################");
while (true) {
sentboxWakeLock.acquire();
performSentboxJobs();
@@ -420,27 +383,16 @@ public class ApplicationDcContext extends DcContext {
}
}
if (smtpThread == null || !smtpThread.isAlive()) {
synchronized (smtpThreadStartedCond) {
smtpThreadStartedVal = false;
}
smtpThread = new Thread(() -> {
smtpWakeLock.acquire();
synchronized (smtpThreadStartedCond) {
smtpThreadStartedVal = true;
smtpThreadStartedCond.notifyAll();
}
Log.i(TAG, "###################### SMTP-Thread started. ######################");
while (true) {
smtpWakeLock.acquire();
performSmtpJobs();
smtpWakeLock.release();
synchronized (incLoopsCritical) {
smtpLoops++;
}
performSmtpIdle();
}
}, "smtpThread");
@@ -450,33 +402,14 @@ public class ApplicationDcContext extends DcContext {
}
}
public void waitForThreadsRunning() {
try {
synchronized (imapThreadStartedCond) {
while (!imapThreadStartedVal) {
imapThreadStartedCond.wait();
public void waitForThreadsExecutedOnce() {
while(true) {
synchronized (incLoopsCritical) {
if(inboxLoops>0 && mvboxLoops>0 && smtpLoops>0) {
break;
}
}
synchronized (mvboxThreadStartedCond) {
while (!mvboxThreadStartedVal) {
mvboxThreadStartedCond.wait();
}
}
synchronized (sentboxThreadStartedCond) {
while (!sentboxThreadStartedVal) {
sentboxThreadStartedCond.wait();
}
}
synchronized (smtpThreadStartedCond) {
while (!smtpThreadStartedVal) {
smtpThreadStartedCond.wait();
}
}
} catch (Exception e) {
e.printStackTrace();
Util.sleep(500);
}
}
@@ -8,10 +8,13 @@ import androidx.work.Worker;
import androidx.work.WorkerParameters;
public class FetchWorker extends Worker {
private @NonNull Context context;
public FetchWorker(
@NonNull Context context,
@NonNull WorkerParameters params) {
super(context, params);
this.context = context;
}
@Override
@@ -20,7 +23,13 @@ public class FetchWorker extends Worker {
// - when no threads are running: fetch-inbox, maybe fetch-mvbox, do smtp-jobs.
// fetch-sendbox is not needed as these messages shall not be notified.
// - when threads are running: interrupt-all-idle
Log.i("DeltaChat", "-------------------- FetchWorker.doWork() --------------------");
Log.i("DeltaChat", "-------------------- FetchWorker.doWork() started --------------------");
ApplicationDcContext dcContext = DcHelper.getContext(context);
dcContext.startThreads(ApplicationDcContext.INTERRUPT_IDLE);
dcContext.waitForThreadsExecutedOnce();
Log.i("DeltaChat", "-------------------- FetchWorker.doWork() done --------------------");
return Result.success(); // when returning, the os may terminate the app again
}
}