fix PausableThread:

set 'mPausing = false' on thread after pause, not on call to proceed()
as the thread may already have been stopped in which case awaitPausing
will loop forever -- short: dont use thread utility classes you havent
written yourself :)
This commit is contained in:
Hannes Janetzek 2014-01-19 14:51:17 +01:00
parent c2eac63ce6
commit 2de6576765

View File

@ -17,12 +17,18 @@
*/ */
package org.oscim.utils; package org.oscim.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* An abstract base class for threads which support pausing and resuming. * An abstract base class for threads which support pausing and resuming.
*/ */
public abstract class PausableThread extends Thread { public abstract class PausableThread extends Thread {
private final static Logger log = LoggerFactory.getLogger(PausableThread.class);
private final static boolean DEBUG = false;
private boolean mPausing = true; private boolean mPausing = true;
private boolean mShouldPause; private boolean mShouldPause = false;
/** /**
* Causes the current thread to wait until this thread is pausing. * Causes the current thread to wait until this thread is pausing.
@ -30,8 +36,10 @@ public abstract class PausableThread extends Thread {
public final void awaitPausing() { public final void awaitPausing() {
synchronized (this) { synchronized (this) {
while (!isInterrupted() && !isPausing()) { while (!isInterrupted() && !isPausing()) {
if (DEBUG)
log.debug("await {}", getThreadName());
try { try {
wait(100); wait(10);
} catch (InterruptedException e) { } catch (InterruptedException e) {
// restore the interrupted status // restore the interrupted status
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
@ -42,17 +50,13 @@ public abstract class PausableThread extends Thread {
@Override @Override
public void interrupt() { public void interrupt() {
if (DEBUG)
log.debug("interrupt {}", getThreadName());
// first acquire the monitor which is used to call wait() // first acquire the monitor which is used to call wait()
synchronized (this) { synchronized (this) {
super.interrupt(); super.interrupt();
} }
//try {
// this.join(10000);
//} catch (InterruptedException e) {
// // restore the interrupted status
// Thread.currentThread().interrupt();
//}
} }
/** /**
@ -72,14 +76,16 @@ public abstract class PausableThread extends Thread {
} }
} }
public final synchronized boolean isCanceled() {
return mShouldPause;
}
/** /**
* The paused thread should continue with its work. * The paused thread should continue with its work.
*/ */
public final synchronized void proceed() { public final synchronized void proceed() {
if (mShouldPause) { if (mShouldPause) {
mShouldPause = false; mShouldPause = false;
mPausing = false;
afterPause();
notify(); notify();
} }
} }
@ -102,6 +108,14 @@ public abstract class PausableThread extends Thread {
interrupt(); interrupt();
} }
} }
if (mPausing) {
mPausing = false;
afterPause();
}
if (DEBUG)
log.debug("resume {}", getThreadName());
} }
if (isInterrupted()) { if (isInterrupted()) {
@ -116,6 +130,11 @@ public abstract class PausableThread extends Thread {
} }
} }
if (DEBUG)
log.debug("finish {}", getThreadName());
mPausing = true;
afterRun(); afterRun();
} }