Skip to content

Commit 867f991

Browse files
authored
Add never, make control flow methods inline (#103)
1 parent 2b164c0 commit 867f991

File tree

3 files changed

+32
-5
lines changed

3 files changed

+32
-5
lines changed

core/src/main/scala/ox/control.scala

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
package ox
22

3-
def forever(f: => Unit): Nothing =
3+
import java.util.concurrent.locks.LockSupport
4+
5+
inline def forever(f: => Unit): Nothing =
46
while true do f
57
throw new RuntimeException("can't get here")
68

79
/** Repeat evaluating `f` while it evaluates to `true`. */
8-
def repeatWhile(f: => Boolean): Unit =
10+
inline def repeatWhile(f: => Boolean): Unit =
911
var loop = true
1012
while loop do loop = f
1113

1214
/** Repeat evaluating `f` until it evaluates to `true`. */
13-
def repeatUntil(f: => Boolean): Unit =
15+
inline def repeatUntil(f: => Boolean): Unit =
1416
var loop = true
1517
while loop do loop = !f
1618

17-
def uninterruptible[T](f: => T): T =
19+
inline def uninterruptible[T](f: => T): T =
1820
scoped {
1921
val t = fork(f)
2022

@@ -27,3 +29,9 @@ def uninterruptible[T](f: => T): T =
2729

2830
joinDespiteInterrupted
2931
}
32+
33+
/** Blocks the current thread indefinitely, until it is interrupted. */
34+
inline def never: Nothing = forever {
35+
LockSupport.park()
36+
if Thread.interrupted() then throw new InterruptedException()
37+
}

core/src/test/scala/ox/ControlTest.scala

+15
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,19 @@ class ControlTest extends AnyFlatSpec with Matchers {
4242

4343
trail.get shouldBe Vector("no timeout", "done")
4444
}
45+
46+
it should "block a thread indefinitely" in {
47+
val trail = Trail()
48+
supervised {
49+
fork {
50+
never
51+
trail.add("never happened!")
52+
}
53+
54+
Thread.sleep(400)
55+
trail.add("done")
56+
}
57+
58+
trail.get shouldBe Vector("done")
59+
}
4560
}

doc/control-flow.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
# Control flow methods
22

3-
There are some helper methods which might be useful when writing forked code:
3+
There are some helper methods which might be useful when writing code using ox's concurrency operators:
44

55
* `forever { ... }` repeatedly evaluates the given code block forever
66
* `repeatWhile { ... }` repeatedly evaluates the given code block, as long as it returns `true`
7+
* `repeatUntil { ... }` repeatedly evaluates the given code block, until it returns `true`
78
* `uninterruptible { ... }` evaluates the given code block making sure it can't be interrupted
9+
* `never` blocks the current thread indefinitely, until it is interrupted
10+
11+
All of these are `inline` methods.

0 commit comments

Comments
 (0)