No locks are needed if everything is executed on main thread

This commit is contained in:
ByteHamster 2019-04-14 13:42:32 +02:00
parent 7c4d4656f8
commit 28f424e3c1
1 changed files with 55 additions and 9 deletions

View File

@ -55,10 +55,12 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
* Some asynchronous calls might change the state of the MediaPlayer object. Therefore calls in other threads * Some asynchronous calls might change the state of the MediaPlayer object. Therefore calls in other threads
* have to wait until these operations have finished. * have to wait until these operations have finished.
*/ */
private final ReentrantLock playerLock; private final PlayerLock playerLock;
private CountDownLatch seekLatch;
private final PlayerExecutor executor; private final PlayerExecutor executor;
private boolean useCallerThread = true;
private CountDownLatch seekLatch;
/** /**
* All ExoPlayer methods must be executed on the same thread. * All ExoPlayer methods must be executed on the same thread.
@ -68,7 +70,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
* Other players are still executed in a background thread. * Other players are still executed in a background thread.
*/ */
private class PlayerExecutor { private class PlayerExecutor {
private boolean useCallerThread = true;
private ThreadPoolExecutor threadPool; private ThreadPoolExecutor threadPool;
public Future<?> submit(Runnable r) { public Future<?> submit(Runnable r) {
@ -85,11 +86,56 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
} }
} }
/**
* All ExoPlayer methods must be executed on the same thread.
* We use the main application thread. This class allows to
* "fake" a lock that does nothing. A lock is not needed if
* everything is called on the same thread.
* Other players are still executed in a background thread and
* therefore use a real lock.
*/
private class PlayerLock {
private ReentrantLock lock = new ReentrantLock();
public void lock() {
if (!useCallerThread) {
lock.lock();
}
}
public boolean tryLock(int i, TimeUnit milliseconds) throws InterruptedException {
if (!useCallerThread) {
return lock.tryLock(i, milliseconds);
}
return true;
}
public boolean tryLock() {
if (!useCallerThread) {
return lock.tryLock();
}
return true;
}
public void unlock() {
if (!useCallerThread) {
lock.unlock();
}
}
public boolean isHeldByCurrentThread() {
if (!useCallerThread) {
return lock.isHeldByCurrentThread();
}
return true;
}
}
public LocalPSMP(@NonNull Context context, public LocalPSMP(@NonNull Context context,
@NonNull PSMPCallback callback) { @NonNull PSMPCallback callback) {
super(context, callback); super(context, callback);
this.audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); this.audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
this.playerLock = new ReentrantLock(); this.playerLock = new PlayerLock();
this.startWhenPrepared = new AtomicBoolean(false); this.startWhenPrepared = new AtomicBoolean(false);
executor = new PlayerExecutor(); executor = new PlayerExecutor();
@ -132,7 +178,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
@Override @Override
public void playMediaObject(@NonNull final Playable playable, final boolean stream, final boolean startWhenPrepared, final boolean prepareImmediately) { public void playMediaObject(@NonNull final Playable playable, final boolean stream, final boolean startWhenPrepared, final boolean prepareImmediately) {
Log.d(TAG, "playMediaObject(...)"); Log.d(TAG, "playMediaObject(...)");
executor.useCallerThread = UserPreferences.useExoplayer(); useCallerThread = UserPreferences.useExoplayer();
executor.submit(() -> { executor.submit(() -> {
playerLock.lock(); playerLock.lock();
try { try {
@ -400,7 +446,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
*/ */
@Override @Override
public void reinit() { public void reinit() {
executor.useCallerThread = UserPreferences.useExoplayer(); useCallerThread = UserPreferences.useExoplayer();
executor.submit(() -> { executor.submit(() -> {
playerLock.lock(); playerLock.lock();
Log.d(TAG, "reinit()"); Log.d(TAG, "reinit()");
@ -850,7 +896,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
@Override @Override
protected Future<?> endPlayback(final boolean hasEnded, final boolean wasSkipped, protected Future<?> endPlayback(final boolean hasEnded, final boolean wasSkipped,
final boolean shouldContinue, final boolean toStoppedState) { final boolean shouldContinue, final boolean toStoppedState) {
executor.useCallerThread = UserPreferences.useExoplayer(); useCallerThread = UserPreferences.useExoplayer();
return executor.submit(() -> { return executor.submit(() -> {
playerLock.lock(); playerLock.lock();
releaseWifiLockIfNecessary(); releaseWifiLockIfNecessary();
@ -1057,7 +1103,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
playerLock.unlock(); playerLock.unlock();
}; };
if (executor.useCallerThread) { if (useCallerThread) {
r.run(); r.run();
} else { } else {
new Thread(r).start(); new Thread(r).start();