Signal-Android/src/org/thoughtcrime/securesms/jobmanager/WorkLockManager.java

95 lines
1.8 KiB
Java

package org.thoughtcrime.securesms.jobmanager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.io.Closeable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Semaphore;
import androidx.work.ListenableWorker.Result;
class WorkLockManager {
private final Map<UUID, WorkLock> locks = new HashMap<>();
WorkLock acquire(@NonNull UUID uuid) {
WorkLock workLock;
synchronized (this) {
workLock = locks.get(uuid);
if (workLock == null) {
workLock = new WorkLock(uuid);
locks.put(uuid, workLock);
}
workLock.increment();
}
workLock.getLock().acquireUninterruptibly();
return workLock;
}
private void release(@NonNull UUID uuid) {
WorkLock lock;
synchronized (this) {
lock = locks.get(uuid);
if (lock == null) {
throw new IllegalStateException("Released a lock that was already removed from use.");
}
if (lock.decrementAndGet() == 0) {
locks.remove(uuid);
}
}
lock.getLock().release();
}
class WorkLock implements Closeable {
private final Semaphore lock;
private final UUID uuid;
private Result result;
private int count;
private WorkLock(@NonNull UUID uuid) {
this.uuid = uuid;
this.lock = new Semaphore(1);
}
private void increment() {
count++;
}
private int decrementAndGet() {
count--;
return count;
}
private @NonNull Semaphore getLock() {
return lock;
}
void setResult(@NonNull Result result) {
this.result = result;
}
@Nullable Result getResult() {
return result;
}
@Override
public void close() {
WorkLockManager.this.release(uuid);
}
}
}