SpinLockSynchronizedState
This commit is contained in:
parent
5e9e741b51
commit
6ea651ce6d
@ -15,7 +15,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "ru.landgrafhomyak.utility"
|
group = "ru.landgrafhomyak.utility"
|
||||||
version = "1.3"
|
version = "1.4"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|||||||
@ -0,0 +1,106 @@
|
|||||||
|
package ru.landgrafhomyak.utility.closeable_state_1;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
public /* open */ class SpinLockSynchronizedState
|
||||||
|
extends SpinLockSynchronizedState$Errors
|
||||||
|
implements CloseableState.ExternallySynchronized {
|
||||||
|
|
||||||
|
private enum State {
|
||||||
|
OPEN, IN_USE, CLOSED
|
||||||
|
}
|
||||||
|
|
||||||
|
private final AtomicReference<State> _currentState;
|
||||||
|
|
||||||
|
public SpinLockSynchronizedState() {
|
||||||
|
this._currentState = new AtomicReference<>(State.OPEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isInUse() {
|
||||||
|
return this._currentState.get() == State.IN_USE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isClosed() {
|
||||||
|
return this._currentState.get() == State.CLOSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void assertNotClosed() {
|
||||||
|
if (this.isClosed())
|
||||||
|
this.throwClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
@Override
|
||||||
|
public final void startUsage() {
|
||||||
|
if (this.startUsageIfNotClosed())
|
||||||
|
this.throwClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
@Override
|
||||||
|
public final boolean startUsageIfNotClosed() {
|
||||||
|
while (true) {
|
||||||
|
switch (this._currentState.compareAndExchange(State.OPEN, State.IN_USE)) {
|
||||||
|
case IN_USE:
|
||||||
|
Thread.onSpinWait();
|
||||||
|
continue;
|
||||||
|
case CLOSED:
|
||||||
|
return true;
|
||||||
|
case OPEN:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _finishUsage(State nextState) {
|
||||||
|
switch (this._currentState.compareAndExchange(State.IN_USE, nextState)) {
|
||||||
|
case OPEN:
|
||||||
|
throw new IllegalStateException("Can't finish usage because it isn't started");
|
||||||
|
case CLOSED:
|
||||||
|
this.throwClosed();
|
||||||
|
case IN_USE:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
@Override
|
||||||
|
public final void finishUsage() {
|
||||||
|
this._finishUsage(State.OPEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
@Override
|
||||||
|
public void finishUsage(boolean close) {
|
||||||
|
this._finishUsage(close ? State.CLOSED : State.OPEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Destructor
|
||||||
|
@ManualStateManipulation
|
||||||
|
@Override
|
||||||
|
public final void close() {
|
||||||
|
switch (this._currentState.compareAndExchange(State.OPEN, State.CLOSED)) {
|
||||||
|
case CLOSED:
|
||||||
|
this.throwClosed();
|
||||||
|
case IN_USE:
|
||||||
|
this.throwInUse();
|
||||||
|
case OPEN:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
switch (this._currentState.get()) {
|
||||||
|
case CLOSED:
|
||||||
|
return "<closeable spinlock-synchronized state [free]>";
|
||||||
|
case IN_USE:
|
||||||
|
return "<closeable spinlock-synchronized state [in use]>";
|
||||||
|
case OPEN:
|
||||||
|
return "<closeable spinlock-synchronized state [closed]>";
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Unreachable");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
@file:OptIn(ExperimentalContracts::class)
|
||||||
|
|
||||||
|
package ru.landgrafhomyak.utility.closeable_state_1
|
||||||
|
|
||||||
|
import kotlin.contracts.ExperimentalContracts
|
||||||
|
|
||||||
|
public class OwnedSpinLockSynchronizedState : SpinLockSynchronizedState {
|
||||||
|
private var _owner: Any?
|
||||||
|
|
||||||
|
public constructor() : super() {
|
||||||
|
this._owner = null
|
||||||
|
}
|
||||||
|
|
||||||
|
public constructor(owner: Any) : super() {
|
||||||
|
this._owner = owner
|
||||||
|
}
|
||||||
|
|
||||||
|
public var owner: Any
|
||||||
|
get() = this._owner ?: throw IllegalStateException("Owner not set yet")
|
||||||
|
set(value) {
|
||||||
|
if (this._owner != null) throw IllegalStateException("Owner already initialized")
|
||||||
|
this._owner = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun throwClosed(): Nothing {
|
||||||
|
throw IllegalStateException("Object is closed: ${this._owner}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun throwInUse(): Nothing {
|
||||||
|
throw IllegalStateException("Failed close object because it is in use: ${this._owner}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
val base = super.toString()
|
||||||
|
return base.substring(0, base.length - 1) + " of ${this._owner}>"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package ru.landgrafhomyak.utility.closeable_state_1
|
||||||
|
|
||||||
|
internal abstract class `SpinLockSynchronizedState$Errors` : CloseableState.ExternallySynchronized {
|
||||||
|
protected open fun throwClosed(): Nothing {
|
||||||
|
throw IllegalStateException("Object is closed")
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun throwInUse(): Nothing {
|
||||||
|
throw IllegalStateException("Failed close object because it is in use")
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user