mirror of
https://github.com/Minestom/Minestom.git
synced 2024-11-02 17:00:41 +01:00
Put implementation detail in AcquirableImpl
This commit is contained in:
parent
b47946bfed
commit
6c3c6e1438
@ -84,12 +84,11 @@ public interface Acquirable<T> {
|
||||
default @NotNull Acquired<T> lock() {
|
||||
var optional = local();
|
||||
if (optional.isPresent()) {
|
||||
return new Acquired<>(optional.get(), false, null);
|
||||
return Acquired.local(optional.get());
|
||||
} else {
|
||||
final Thread currentThread = Thread.currentThread();
|
||||
final TickThread tickThread = getHandler().getTickThread();
|
||||
var lock = Acquired.acquireEnter(currentThread, tickThread);
|
||||
return new Acquired<>(unwrap(), true, lock);
|
||||
return Acquired.locked(unwrap(), currentThread, tickThread);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,11 @@ public class AcquirableCollection<E> implements Collection<Acquirable<E>> {
|
||||
final TickThread tickThread = entry.getKey();
|
||||
final List<E> values = entry.getValue();
|
||||
|
||||
var lock = Acquired.acquireEnter(currentThread, tickThread);
|
||||
var lock = AcquirableImpl.enter(currentThread, tickThread);
|
||||
for (E value : values) {
|
||||
consumer.accept(value);
|
||||
}
|
||||
Acquired.acquireLeave(lock);
|
||||
AcquirableImpl.leave(lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
package net.minestom.server.acquirable;
|
||||
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.thread.TickThread;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class AcquirableImpl<T> implements Acquirable<T> {
|
||||
@ -11,6 +14,11 @@ class AcquirableImpl<T> implements Acquirable<T> {
|
||||
protected static final ThreadLocal<Stream<Entity>> CURRENT_ENTITIES = ThreadLocal.withInitial(Stream::empty);
|
||||
protected static final AtomicLong WAIT_COUNTER_NANO = new AtomicLong();
|
||||
|
||||
/**
|
||||
* Global lock used for synchronization.
|
||||
*/
|
||||
private static final ReentrantLock GLOBAL_LOCK = new ReentrantLock();
|
||||
|
||||
private final T value;
|
||||
private final Acquirable.Handler handler;
|
||||
|
||||
@ -28,4 +36,42 @@ class AcquirableImpl<T> implements Acquirable<T> {
|
||||
public @NotNull Acquirable.Handler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
protected static @Nullable ReentrantLock enter(@Nullable Thread currentThread, @Nullable TickThread elementThread) {
|
||||
// Monitoring
|
||||
long time = System.nanoTime();
|
||||
|
||||
ReentrantLock currentLock;
|
||||
{
|
||||
final TickThread current = currentThread instanceof TickThread ?
|
||||
(TickThread) currentThread : null;
|
||||
currentLock = current != null && current.getLock().isHeldByCurrentThread() ?
|
||||
current.getLock() : null;
|
||||
}
|
||||
if (currentLock != null)
|
||||
currentLock.unlock();
|
||||
|
||||
GLOBAL_LOCK.lock();
|
||||
|
||||
if (currentLock != null)
|
||||
currentLock.lock();
|
||||
|
||||
final var lock = elementThread != null ? elementThread.getLock() : null;
|
||||
final boolean acquired = lock == null || lock.isHeldByCurrentThread();
|
||||
if (!acquired) {
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
// Monitoring
|
||||
AcquirableImpl.WAIT_COUNTER_NANO.addAndGet(System.nanoTime() - time);
|
||||
|
||||
return !acquired ? lock : null;
|
||||
}
|
||||
|
||||
protected static void leave(@Nullable ReentrantLock lock) {
|
||||
if (lock != null) {
|
||||
lock.unlock();
|
||||
}
|
||||
GLOBAL_LOCK.unlock();
|
||||
}
|
||||
}
|
||||
|
@ -3,17 +3,11 @@ package net.minestom.server.acquirable;
|
||||
import net.minestom.server.thread.TickThread;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class Acquired<T> {
|
||||
|
||||
/**
|
||||
* Global lock used for synchronization.
|
||||
*/
|
||||
private static final ReentrantLock GLOBAL_LOCK = new ReentrantLock();
|
||||
|
||||
private final T value;
|
||||
|
||||
private final boolean locked;
|
||||
@ -21,11 +15,19 @@ public class Acquired<T> {
|
||||
|
||||
private boolean unlocked;
|
||||
|
||||
protected Acquired(@NotNull T value,
|
||||
boolean locked, @Nullable ReentrantLock lock) {
|
||||
protected static <T> Acquired<T> local(@NotNull T value) {
|
||||
return new Acquired<>(value, false, null, null);
|
||||
}
|
||||
|
||||
protected static <T> Acquired<T> locked(@NotNull T value, Thread currentThread, TickThread tickThread) {
|
||||
return new Acquired<>(value, true, currentThread, tickThread);
|
||||
}
|
||||
|
||||
private Acquired(@NotNull T value,
|
||||
boolean locked, Thread currentThread, TickThread tickThread) {
|
||||
this.value = value;
|
||||
this.locked = locked;
|
||||
this.lock = lock;
|
||||
this.lock = locked ? AcquirableImpl.enter(currentThread, tickThread) : null;
|
||||
}
|
||||
|
||||
public @NotNull T get() {
|
||||
@ -38,45 +40,7 @@ public class Acquired<T> {
|
||||
this.unlocked = true;
|
||||
if (!locked)
|
||||
return;
|
||||
acquireLeave(lock);
|
||||
}
|
||||
|
||||
protected static @Nullable ReentrantLock acquireEnter(@Nullable Thread currentThread, @Nullable TickThread elementThread) {
|
||||
// Monitoring
|
||||
long time = System.nanoTime();
|
||||
|
||||
ReentrantLock currentLock;
|
||||
{
|
||||
final TickThread current = currentThread instanceof TickThread ?
|
||||
(TickThread) currentThread : null;
|
||||
currentLock = current != null && current.getLock().isHeldByCurrentThread() ?
|
||||
current.getLock() : null;
|
||||
}
|
||||
if (currentLock != null)
|
||||
currentLock.unlock();
|
||||
|
||||
GLOBAL_LOCK.lock();
|
||||
|
||||
if (currentLock != null)
|
||||
currentLock.lock();
|
||||
|
||||
final var lock = elementThread != null ? elementThread.getLock() : null;
|
||||
final boolean acquired = lock == null || lock.isHeldByCurrentThread();
|
||||
if (!acquired) {
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
// Monitoring
|
||||
AcquirableImpl.WAIT_COUNTER_NANO.addAndGet(System.nanoTime() - time);
|
||||
|
||||
return !acquired ? lock : null;
|
||||
}
|
||||
|
||||
protected static void acquireLeave(@Nullable ReentrantLock lock) {
|
||||
if (lock != null) {
|
||||
lock.unlock();
|
||||
}
|
||||
GLOBAL_LOCK.unlock();
|
||||
AcquirableImpl.leave(lock);
|
||||
}
|
||||
|
||||
private void checkLock() {
|
||||
|
Loading…
Reference in New Issue
Block a user