startUsageIfNotClosed
This commit is contained in:
parent
4ff6c0beb3
commit
8fc08d3e26
@ -82,6 +82,7 @@ xomrk {
|
|||||||
|
|
||||||
jvmTest {
|
jvmTest {
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation(kotlinStdlibDependency)
|
||||||
implementation("org.testng:testng:7.5.1")
|
implementation("org.testng:testng:7.5.1")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,10 @@ public sealed class ChildCloseableState<T : CloseableState> : CloseableState {
|
|||||||
override fun startUsage(): Unit =
|
override fun startUsage(): Unit =
|
||||||
this._state.startUsage()
|
this._state.startUsage()
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
override fun startUsageIfNotClosed(): Boolean =
|
||||||
|
this._state.startUsageIfNotClosed()
|
||||||
|
|
||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
override fun finishUsage(): Unit =
|
override fun finishUsage(): Unit =
|
||||||
this._state.finishUsage()
|
this._state.finishUsage()
|
||||||
|
|||||||
@ -8,6 +8,13 @@ public interface CloseableState {
|
|||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
public fun startUsage()
|
public fun startUsage()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to start usage and returns `false` if entered or `true` if closed.
|
||||||
|
* Doesn't prevent from throwing error if this state forbids concurrent access.
|
||||||
|
*/
|
||||||
|
@ManualStateManipulation
|
||||||
|
public fun startUsageIfNotClosed(): Boolean
|
||||||
|
|
||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
public fun finishUsage()
|
public fun finishUsage()
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,9 @@ public expect class CloseableStateCloseableWrapper : CloseableState.ExternallySy
|
|||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
override fun startUsage()
|
override fun startUsage()
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
override fun startUsageIfNotClosed(): Boolean
|
||||||
|
|
||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
override fun finishUsage()
|
override fun finishUsage()
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,9 @@ public expect open class ErrorOnConcurrentAccessState : CloseableState.Externall
|
|||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
public final override fun startUsage()
|
public final override fun startUsage()
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
public final override fun startUsageIfNotClosed(): Boolean
|
||||||
|
|
||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
public final override fun finishUsage()
|
public final override fun finishUsage()
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,9 @@ public expect open class UsagesCounter : CloseableState.AllowsConcurrency {
|
|||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
public final override fun startUsage()
|
public final override fun startUsage()
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
public final override fun startUsageIfNotClosed(): Boolean
|
||||||
|
|
||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
public final override fun finishUsage()
|
public final override fun finishUsage()
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,7 @@ public final class jCloseableStateCloseableWrapper
|
|||||||
this._self.assertNotClosed();
|
this._self.assertNotClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
@Override
|
@Override
|
||||||
public void startUsage() {
|
public void startUsage() {
|
||||||
this._self.startUsage();
|
this._self.startUsage();
|
||||||
@ -46,12 +47,35 @@ public final class jCloseableStateCloseableWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
@Override
|
||||||
|
public boolean startUsageIfNotClosed() {
|
||||||
|
if (this._self.startUsageIfNotClosed())
|
||||||
|
return true;
|
||||||
|
try {
|
||||||
|
if (this._parent.startUsageIfNotClosed()) {
|
||||||
|
this._self.finishUsage();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Throwable e1) {
|
||||||
|
try {
|
||||||
|
this._self.finishUsage();
|
||||||
|
} catch (Throwable e2) {
|
||||||
|
e1.addSuppressed(e2);
|
||||||
|
}
|
||||||
|
throw e1;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
@Override
|
@Override
|
||||||
public void finishUsage() {
|
public void finishUsage() {
|
||||||
this._parent.finishUsage();
|
this._parent.finishUsage();
|
||||||
this._self.finishUsage();
|
this._self.finishUsage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
@Override
|
@Override
|
||||||
public void finishUsage(boolean close) {
|
public void finishUsage(boolean close) {
|
||||||
this._parent.finishUsage();
|
this._parent.finishUsage();
|
||||||
@ -59,6 +83,7 @@ public final class jCloseableStateCloseableWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Destructor
|
@Destructor
|
||||||
|
@ManualStateManipulation
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
this._self.close();
|
this._self.close();
|
||||||
@ -68,4 +93,5 @@ public final class jCloseableStateCloseableWrapper
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "<closeable state " + this._parent + " wrapped with " + this._self + ">";
|
return "<closeable state " + this._parent + " wrapped with " + this._self + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,16 +32,25 @@ public /* open */ class jErrorOnConcurrentAccessState
|
|||||||
this.throwClosed();
|
this.throwClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
@Override
|
@Override
|
||||||
public final void startUsage() {
|
public final void startUsage() {
|
||||||
|
if (this.startUsageIfNotClosed())
|
||||||
|
this.throwClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
@Override
|
||||||
|
public final boolean startUsageIfNotClosed() {
|
||||||
switch (this._currentState.compareAndExchange(State.OPEN, State.IN_USE)) {
|
switch (this._currentState.compareAndExchange(State.OPEN, State.IN_USE)) {
|
||||||
case IN_USE:
|
case IN_USE:
|
||||||
this.throwConcurrent();
|
this.throwConcurrent();
|
||||||
case CLOSED:
|
case CLOSED:
|
||||||
this.throwClosed();
|
return true;
|
||||||
case OPEN:
|
case OPEN:
|
||||||
break;
|
return false;
|
||||||
}
|
}
|
||||||
|
throw new RuntimeException("Unreachable");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _finishUsage(State nextState) {
|
private void _finishUsage(State nextState) {
|
||||||
@ -55,17 +64,20 @@ public /* open */ class jErrorOnConcurrentAccessState
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
@Override
|
@Override
|
||||||
public final void finishUsage() {
|
public final void finishUsage() {
|
||||||
this._finishUsage(State.OPEN);
|
this._finishUsage(State.OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
@Override
|
@Override
|
||||||
public void finishUsage(boolean close) {
|
public void finishUsage(boolean close) {
|
||||||
this._finishUsage(close ? State.CLOSED : State.OPEN);
|
this._finishUsage(close ? State.CLOSED : State.OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Destructor
|
@Destructor
|
||||||
|
@ManualStateManipulation
|
||||||
@Override
|
@Override
|
||||||
public final void close() {
|
public final void close() {
|
||||||
switch (this._currentState.compareAndExchange(State.OPEN, State.CLOSED)) {
|
switch (this._currentState.compareAndExchange(State.OPEN, State.CLOSED)) {
|
||||||
|
|||||||
@ -22,20 +22,28 @@ public /* open */ class jUsagesCounter
|
|||||||
this.throwClosed();
|
this.throwClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
@Override
|
@Override
|
||||||
public final void startUsage() {
|
public final void startUsage() {
|
||||||
|
if (this.startUsageIfNotClosed())
|
||||||
|
this.throwClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
@Override
|
||||||
|
public final boolean startUsageIfNotClosed() {
|
||||||
while (true) {
|
while (true) {
|
||||||
final long cur = this._currentUsagesCount.get();
|
final long cur = this._currentUsagesCount.get();
|
||||||
if (cur < 0) {
|
if (cur < 0) {
|
||||||
this.throwClosed();
|
return true;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._currentUsagesCount.compareAndSet(cur, cur + 1))
|
if (this._currentUsagesCount.compareAndSet(cur, cur + 1))
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
@Override
|
@Override
|
||||||
public final void finishUsage() {
|
public final void finishUsage() {
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -51,6 +59,7 @@ public /* open */ class jUsagesCounter
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Destructor
|
@Destructor
|
||||||
|
@ManualStateManipulation
|
||||||
@Override
|
@Override
|
||||||
public final void close() {
|
public final void close() {
|
||||||
long currentReferencesCount;
|
long currentReferencesCount;
|
||||||
|
|||||||
@ -36,6 +36,26 @@ public actual class CloseableStateCloseableWrapper : CloseableState.ExternallySy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
actual override fun startUsageIfNotClosed(): Boolean {
|
||||||
|
if (this._self.startUsageIfNotClosed())
|
||||||
|
return true
|
||||||
|
try {
|
||||||
|
if (this._parent.startUsageIfNotClosed()) {
|
||||||
|
this._self.finishUsage()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} catch (e1: Throwable) {
|
||||||
|
try {
|
||||||
|
this._self.finishUsage()
|
||||||
|
} catch (e2: Throwable) {
|
||||||
|
e1.addSuppressed(e2)
|
||||||
|
}
|
||||||
|
throw e1
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
actual override fun finishUsage() {
|
actual override fun finishUsage() {
|
||||||
this._parent.finishUsage()
|
this._parent.finishUsage()
|
||||||
|
|||||||
@ -35,10 +35,16 @@ public actual open class ErrorOnConcurrentAccessState : CloseableState.Externall
|
|||||||
|
|
||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
public actual final override fun startUsage() {
|
public actual final override fun startUsage() {
|
||||||
|
if (this.startUsageIfNotClosed())
|
||||||
|
this.throwClosed()
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
public actual final override fun startUsageIfNotClosed(): Boolean {
|
||||||
when (this._state.compareAndExchange(State.OPEN, State.IN_USE)) {
|
when (this._state.compareAndExchange(State.OPEN, State.IN_USE)) {
|
||||||
State.OPEN -> {}
|
State.OPEN -> return false;
|
||||||
State.IN_USE -> this.throwConcurrent()
|
State.IN_USE -> this.throwConcurrent()
|
||||||
State.CLOSED -> this.throwClosed()
|
State.CLOSED -> return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,15 @@ public actual open class UsagesCounter : CloseableState.AllowsConcurrency {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ManualStateManipulation
|
||||||
|
public actual final override fun startUsageIfNotClosed(): Boolean {
|
||||||
|
this._value.update { o ->
|
||||||
|
if (o < 0) return true
|
||||||
|
return@update o + 1
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
public actual final override fun finishUsage() {
|
public actual final override fun finishUsage() {
|
||||||
this._value.update(Long::dec)
|
this._value.update(Long::dec)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user