/** * Copyright (c) 2016, All Contributors (see CONTRIBUTORS file) * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package com.eventsourcing; import com.google.common.util.concurrent.AbstractService; import org.osgi.service.component.annotations.Component; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Semaphore; /** * Local, in-memory lock provider */ @Component(property = {"type=LocalLockProvider"}) public class LocalLockProvider extends AbstractService implements LockProvider { private Map<Object, Semaphore> locks = new HashMap<>(); @Override public Lock lock(Object lock) { Semaphore semaphore = locks.containsKey(lock) ? locks.get(lock) : new Semaphore(1); locks.put(lock, semaphore); semaphore.acquireUninterruptibly(); return new LocalLock(semaphore); } @Override protected void doStart() { notifyStarted(); } @Override protected void doStop() { notifyStopped(); } static class LocalLock implements Lock { private final Semaphore semaphore; public LocalLock(Semaphore semaphore) { this.semaphore = semaphore; } @Override public void unlock() { semaphore.release(); } @Override public boolean isLocked() { return semaphore.availablePermits() == 0; } } }