@@ -31,10 +31,10 @@ extension Task where Success == Never, Failure == Never {
31
31
32
32
/// The type of continuation used in the implementation of
33
33
/// sleep(nanoseconds:).
34
- private typealias SleepContinuation = UnsafeContinuation < ( ) , Error >
34
+ typealias SleepContinuation = UnsafeContinuation < ( ) , Error >
35
35
36
36
/// Describes the state of a sleep() operation.
37
- private enum SleepState {
37
+ enum SleepState {
38
38
/// The sleep continuation has not yet begun.
39
39
case notStarted
40
40
@@ -106,7 +106,7 @@ extension Task where Success == Never, Failure == Never {
106
106
107
107
/// Called when the sleep(nanoseconds:) operation woke up without being
108
108
/// canceled.
109
- private static func onSleepWake(
109
+ static func onSleepWake(
110
110
_ wordPtr: UnsafeMutablePointer < Builtin . Word >
111
111
) {
112
112
while true {
@@ -150,7 +150,7 @@ extension Task where Success == Never, Failure == Never {
150
150
151
151
/// Called when the sleep(nanoseconds:) operation has been canceled before
152
152
/// the sleep completed.
153
- private static func onSleepCancel(
153
+ static func onSleepCancel(
154
154
_ wordPtr: UnsafeMutablePointer < Builtin . Word >
155
155
) {
156
156
while true {
@@ -294,133 +294,4 @@ extension Task where Success == Never, Failure == Never {
294
294
throw error
295
295
}
296
296
}
297
-
298
- @available ( SwiftStdlib 5 . 7 , * )
299
- internal static func _sleep(
300
- until seconds: Int64 , _ nanoseconds: Int64 ,
301
- tolerance: Duration ? ,
302
- clock: _ClockID
303
- ) async throws {
304
- // Allocate storage for the storage word.
305
- let wordPtr = UnsafeMutablePointer< Builtin . Word> . allocate( capacity: 1 )
306
-
307
- // Initialize the flag word to "not started", which means the continuation
308
- // has neither been created nor completed.
309
- Builtin . atomicstore_seqcst_Word (
310
- wordPtr. _rawValue, SleepState . notStarted. word. _builtinWordValue)
311
-
312
- do {
313
- // Install a cancellation handler to resume the continuation by
314
- // throwing CancellationError.
315
- try await withTaskCancellationHandler {
316
- let _: ( ) = try await withUnsafeThrowingContinuation { continuation in
317
- while true {
318
- let state = SleepState ( loading: wordPtr)
319
- switch state {
320
- case . notStarted:
321
- // The word that describes the active continuation state.
322
- let continuationWord =
323
- SleepState . activeContinuation ( continuation) . word
324
-
325
- // Try to swap in the continuation word.
326
- let ( _, won) = Builtin . cmpxchg_seqcst_seqcst_Word (
327
- wordPtr. _rawValue,
328
- state. word. _builtinWordValue,
329
- continuationWord. _builtinWordValue)
330
- if !Bool( _builtinBooleanLiteral: won) {
331
- // Keep trying!
332
- continue
333
- }
334
-
335
- // Create a task that resumes the continuation normally if it
336
- // finishes first. Enqueue it directly with the delay, so it fires
337
- // when we're done sleeping.
338
- let sleepTaskFlags = taskCreateFlags (
339
- priority: nil , isChildTask: false , copyTaskLocals: false ,
340
- inheritContext: false , enqueueJob: false ,
341
- addPendingGroupTaskUnconditionally: false )
342
- let ( sleepTask, _) = Builtin . createAsyncTask ( sleepTaskFlags) {
343
- onSleepWake ( wordPtr)
344
- }
345
- let toleranceSeconds : Int64
346
- let toleranceNanoseconds : Int64
347
- if let components = tolerance? . components {
348
- toleranceSeconds = components. seconds
349
- toleranceNanoseconds = components. attoseconds / 1_000_000_000
350
- } else {
351
- toleranceSeconds = 0
352
- toleranceNanoseconds = - 1
353
- }
354
-
355
- _enqueueJobGlobalWithDeadline (
356
- seconds, nanoseconds,
357
- toleranceSeconds, toleranceNanoseconds,
358
- clock. rawValue, Builtin . convertTaskToJob ( sleepTask) )
359
- return
360
-
361
- case . activeContinuation, . finished:
362
- fatalError ( " Impossible to have multiple active continuations " )
363
-
364
- case . cancelled:
365
- fatalError ( " Impossible to have cancelled before we began " )
366
-
367
- case . cancelledBeforeStarted:
368
- // Finish the continuation normally. We'll throw later, after
369
- // we clean up.
370
- continuation. resume ( )
371
- return
372
- }
373
- }
374
- }
375
- } onCancel: {
376
- onSleepCancel ( wordPtr)
377
- }
378
-
379
- // Determine whether we got cancelled before we even started.
380
- let cancelledBeforeStarted : Bool
381
- switch SleepState ( loading: wordPtr) {
382
- case . notStarted, . activeContinuation, . cancelled:
383
- fatalError ( " Invalid state for non-cancelled sleep task " )
384
-
385
- case . cancelledBeforeStarted:
386
- cancelledBeforeStarted = true
387
-
388
- case . finished:
389
- cancelledBeforeStarted = false
390
- }
391
-
392
- // We got here without being cancelled, so deallocate the storage for
393
- // the flag word and continuation.
394
- wordPtr. deallocate ( )
395
-
396
- // If we got cancelled before we even started, through the cancellation
397
- // error now.
398
- if cancelledBeforeStarted {
399
- throw _Concurrency. CancellationError ( )
400
- }
401
- } catch {
402
- // The task was cancelled; propagate the error. The "on wake" task is
403
- // responsible for deallocating the flag word and continuation, if it's
404
- // still running.
405
- throw error
406
- }
407
- }
408
-
409
- /// Suspends the current task until the given deadline within a tolerance.
410
- ///
411
- /// If the task is canceled before the time ends, this function throws
412
- /// `CancellationError`.
413
- ///
414
- /// This function doesn't block the underlying thread.
415
- ///
416
- /// try await Task.sleep(until: .now + .seconds(3), clock: .continuous)
417
- ///
418
- @available ( SwiftStdlib 5 . 7 , * )
419
- public static func sleep< C: Clock > (
420
- until deadline: C . Instant ,
421
- tolerance: C . Instant . Duration ? = nil ,
422
- clock: C
423
- ) async throws {
424
- try await clock. sleep ( until: deadline, tolerance: tolerance)
425
- }
426
297
}
0 commit comments