Skip to content

Commit f8a67ce

Browse files
committed
feat: bring over stop
1 parent 6fb01ae commit f8a67ce

File tree

1 file changed

+43
-20
lines changed

1 file changed

+43
-20
lines changed

src/Std/Internal/Async.lean

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -81,22 +81,22 @@ structure Sleep where
8181
private ofNative ::
8282
native : Internal.UV.Timer
8383

84-
-- TODO: provable constraints on duration after changes in Std.Time
85-
8684
namespace Sleep
8785

8886
/--
8987
Set up a `Sleep` that waits for `duration` milliseconds.
90-
This function only initializes but does not yet start the underlying timer.
88+
This function only initializes but does not yet start the timer.
9189
-/
9290
@[inline]
9391
def mk (duration : Std.Time.Millisecond.Offset) : IO Sleep := do
9492
let native ← Internal.UV.Timer.mk duration.toInt.toNat.toUInt64 false
9593
return ofNative native
9694

9795
/--
98-
Start the underlying timer of `s` and return an `AsyncTask` that will resolve once the previously
99-
configured duration has run out. Running this function twice returns the same `AsyncTask`.
96+
If:
97+
- `s` is not yet running start it and return an `AsyncTask` that will resolve once the previously
98+
configured `duration` has run out.
99+
- `s` is already or not anymore running return the same `AsyncTask` as the first call to `wait`.
100100
-/
101101
@[inline]
102102
def wait (s : Sleep) : IO (AsyncTask Unit) := do
@@ -105,14 +105,25 @@ def wait (s : Sleep) : IO (AsyncTask Unit) := do
105105

106106
/--
107107
If:
108-
- `Sleep.wait` was previously called on `s` this makes the timer wait for `duration` counting from
109-
the call of this function.
110-
- `Sleep.wait` was never called on `s` before this is a no-op.
108+
- `s` is still running this will delay the resolution of `AsyncTask`s created with `wait` by
109+
`duration` milliseconds.
110+
- `s` is not yet or not anymore running this is a no-op.
111111
-/
112112
@[inline]
113113
def reset (s : Sleep) : IO Unit :=
114114
s.native.reset
115115

116+
/--
117+
If:
118+
- `s` is still running this stops `s` without resolving any remaing `AsyncTask` that were created
119+
through `wait`. Note that if another `AsyncTask` is binding on any of these it is going hang
120+
forever without further intervention.
121+
- `s` is not yet or not anymore running this is a no-op.
122+
-/
123+
@[inline]
124+
def stop (s : Sleep) : IO Unit :=
125+
s.native.stop
126+
116127
end Sleep
117128

118129
/--
@@ -135,22 +146,23 @@ namespace Interval
135146

136147
/--
137148
Setup up an `Interval` that waits for `duration` milliseconds.
138-
This function only initializes but does not yet start the underlying timer.
149+
This function only initializes but does not yet start the timer.
139150
-/
140151
@[inline]
141152
def mk (duration : Std.Time.Millisecond.Offset) : IO Interval := do
142153
let native ← Internal.UV.Timer.mk duration.toInt.toNat.toUInt64 true
143154
return ofNative native
144155

145156
/--
146-
Start the underlying timer of `s` and return an `AsyncTask` that will resolve upon the next tick
147-
of `i`. In particular:
148-
- calling this function for the first time starts the underlying timer of `i` and returns an
149-
`AsyncTask` that instantly resolves as the 0th multiple of `duration` has elapsed.
150-
- calling this function while the tick from the last call has not yet finished returns the same
151-
`AsyncTask` as the last call.
152-
- calling this function when the tick from the last call has finished returns a new `AsyncTask`
153-
that waits for the closest next tick from the time of calling this function.
157+
If:
158+
- `i` is not yet running start it and return an `AsyncTask` that resolves right away as the 0th
159+
multiple of `duration` has elapsed.
160+
- `i` is already running and:
161+
- the tick from the last call of `i` has not yet finished return the same `AsyncTask` as the last
162+
call
163+
- the tick frrom the last call of `i` has finished return a new `AsyncTask` that waits for the
164+
closest next tick from the time of calling this function.
165+
- `i` is not running aymore this is a no-op.
154166
-/
155167
@[inline]
156168
def tick (i : Interval) : IO (AsyncTask Unit) := do
@@ -159,14 +171,25 @@ def tick (i : Interval) : IO (AsyncTask Unit) := do
159171

160172
/--
161173
If:
162-
- `Interval.tick` was called on `i` before the next internal timer restarts counting from now and
163-
the next tick happens in `duration`.
164-
- `Interval.tick` was never called on `i` before this is a no-op.
174+
- `Interval.tick` was called on `i` before the timer restarts counting from now and the next tick
175+
happens in `duration`.
176+
- `i` is not yet or not anymore running this is a no-op.
165177
-/
166178
@[inline]
167179
def reset (i : Interval) : IO Unit :=
168180
i.native.reset
169181

182+
/--
183+
If:
184+
- `i` is still running this stops `i` without resolving any remaing `AsyncTask` that were created
185+
through `tick`. Note that if another `AsyncTask` is binding on any of these it is going hang
186+
forever without further intervention.
187+
- `i` is not yet or not anymore running this is a no-op.
188+
-/
189+
@[inline]
190+
def stop (i : Interval) : IO Unit :=
191+
i.native.stop
192+
170193
end Interval
171194

172195
end Async

0 commit comments

Comments
 (0)