Compare commits

...

2 Commits
v1.3 ... master

4 changed files with 151 additions and 1 deletions

View File

@ -15,7 +15,7 @@ buildscript {
}
group = "ru.landgrafhomyak.utility"
version = "1.3"
version = "1.4"
repositories {
mavenCentral()

View File

@ -0,0 +1,110 @@
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() {
while (true) {
switch (this._currentState.compareAndExchange(State.OPEN, State.CLOSED)) {
case CLOSED:
this.throwClosed();
case IN_USE:
Thread.onSpinWait();
continue;
case OPEN:
return;
}
}
}
@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");
}
}

View File

@ -0,0 +1,33 @@
@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 toString(): String {
val base = super.toString()
return base.substring(0, base.length - 1) + " of ${this._owner}>"
}
}

View File

@ -0,0 +1,7 @@
package ru.landgrafhomyak.utility.closeable_state_1
internal abstract class `SpinLockSynchronizedState$Errors` : CloseableState.ExternallySynchronized {
protected open fun throwClosed(): Nothing {
throw IllegalStateException("Object is closed")
}
}