@@ -36,9 +36,12 @@ import Swift
36
36
/// individually schedulable as jobs. Jobs are generally not interacted
37
37
/// with by end-users directly, unless implementing a scheduler.
38
38
@available ( SwiftStdlib 5 . 5 , * )
39
+ @frozen
39
40
public struct Task < Success, Failure: Error > : Sendable {
41
+ @usableFromInline
40
42
internal let _task : Builtin . NativeObject
41
43
44
+ @_alwaysEmitIntoClient
42
45
internal init ( _ task: Builtin . NativeObject ) {
43
46
self . _task = task
44
47
}
@@ -381,109 +384,32 @@ struct JobFlags {
381
384
382
385
// ==== Task Creation Flags --------------------------------------------------
383
386
384
- /// Flags for schedulable jobs.
385
- ///
386
- /// This is a port of the C++ FlagSet.
387
+ /// Form task creation flags for use with the createAsyncTask builtins.
387
388
@available ( SwiftStdlib 5 . 5 , * )
388
- struct TaskCreateFlags {
389
- /// The actual bit representation of these flags.
390
- var bits : Int = 0
391
-
392
- /// The priority given to the job.
393
- var priority : TaskPriority ? {
394
- get {
395
- let value = Int ( bits) & 0xFF
396
-
397
- if value == 0 {
398
- return nil
399
- }
400
-
401
- return TaskPriority ( rawValue: UInt8 ( value) )
402
- }
403
-
404
- set {
405
- bits = ( bits & ~ 0xFF ) | Int ( newValue? . rawValue ?? 0 )
406
- }
407
- }
408
-
409
- /// Whether this is a child task.
410
- var isChildTask : Bool {
411
- get {
412
- ( bits & ( 1 << 8 ) ) != 0
413
- }
414
-
415
- set {
416
- if newValue {
417
- bits = bits | 1 << 8
418
- } else {
419
- bits = ( bits & ~ ( 1 << 8 ) )
420
- }
421
- }
389
+ @_alwaysEmitIntoClient
390
+ func taskCreateFlags(
391
+ priority: TaskPriority ? , isChildTask: Bool , copyTaskLocals: Bool ,
392
+ inheritContext: Bool , enqueueJob: Bool ,
393
+ addPendingGroupTaskUnconditionally: Bool
394
+ ) -> Int {
395
+ var bits = 0
396
+ bits |= ( bits & ~ 0xFF ) | Int ( priority? . rawValue ?? 0 )
397
+ if isChildTask {
398
+ bits |= 1 << 8
422
399
}
423
-
424
- /// Whether to copy thread locals from the currently-executing task into the
425
- /// newly-created task.
426
- var copyTaskLocals : Bool {
427
- get {
428
- ( bits & ( 1 << 10 ) ) != 0
429
- }
430
-
431
- set {
432
- if newValue {
433
- bits = bits | 1 << 10
434
- } else {
435
- bits = ( bits & ~ ( 1 << 10 ) )
436
- }
437
- }
400
+ if copyTaskLocals {
401
+ bits |= 1 << 10
438
402
}
439
-
440
- /// Whether this task should inherit as much context from the
441
- /// currently-executing task as it can.
442
- var inheritContext : Bool {
443
- get {
444
- ( bits & ( 1 << 11 ) ) != 0
445
- }
446
-
447
- set {
448
- if newValue {
449
- bits = bits | 1 << 11
450
- } else {
451
- bits = ( bits & ~ ( 1 << 11 ) )
452
- }
453
- }
403
+ if inheritContext {
404
+ bits |= 1 << 11
454
405
}
455
-
456
- /// Whether to enqueue the newly-created task on the given executor (if
457
- /// specified) or the global executor.
458
- var enqueueJob : Bool {
459
- get {
460
- ( bits & ( 1 << 12 ) ) != 0
461
- }
462
-
463
- set {
464
- if newValue {
465
- bits = bits | 1 << 12
466
- } else {
467
- bits = ( bits & ~ ( 1 << 12 ) )
468
- }
469
- }
406
+ if enqueueJob {
407
+ bits |= 1 << 12
470
408
}
471
-
472
- /// Whether to add a pending group task unconditionally as part of creating
473
- /// the task.
474
- var addPendingGroupTaskUnconditionally : Bool {
475
- get {
476
- ( bits & ( 1 << 13 ) ) != 0
477
- }
478
-
479
- set {
480
- if newValue {
481
- bits = bits | 1 << 13
482
- } else {
483
- bits = ( bits & ~ ( 1 << 13 ) )
484
- }
485
- }
409
+ if addPendingGroupTaskUnconditionally {
410
+ bits |= 1 << 13
486
411
}
412
+ return bits
487
413
}
488
414
489
415
// ==== Task Creation ----------------------------------------------------------
@@ -506,20 +432,20 @@ extension Task where Failure == Never {
506
432
/// Task.currentPriority.
507
433
/// - operation: the operation to execute
508
434
@discardableResult
435
+ @_alwaysEmitIntoClient
509
436
public init (
510
437
priority: TaskPriority ? = nil ,
511
438
@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping ( ) async -> Success
512
439
) {
513
440
#if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
514
441
// Set up the job flags for a new task.
515
- var flags = TaskCreateFlags ( )
516
- flags. priority = priority
517
- flags. inheritContext = true
518
- flags. copyTaskLocals = true
519
- flags. enqueueJob = true
442
+ let flags = taskCreateFlags (
443
+ priority: priority, isChildTask: false , copyTaskLocals: true ,
444
+ inheritContext: true , enqueueJob: true ,
445
+ addPendingGroupTaskUnconditionally: false )
520
446
521
447
// Create the asynchronous task.
522
- let ( task, _) = Builtin . createAsyncTask ( Int ( flags. bits ) , operation)
448
+ let ( task, _) = Builtin . createAsyncTask ( flags, operation)
523
449
524
450
self . _task = task
525
451
#else
@@ -543,20 +469,21 @@ extension Task where Failure == Error {
543
469
/// Task.currentPriority.
544
470
/// - operation: the operation to execute
545
471
@discardableResult
472
+ @_alwaysEmitIntoClient
546
473
public init (
547
474
priority: TaskPriority ? = nil ,
548
475
@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping ( ) async throws -> Success
549
476
) {
550
477
#if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
551
- // Set up the job flags for a new task.
552
- var flags = TaskCreateFlags ( )
553
- flags . priority = priority
554
- flags . inheritContext = true
555
- flags . copyTaskLocals = true
556
- flags . enqueueJob = true
478
+ // Set up the task flags for a new task.
479
+ let flags = taskCreateFlags (
480
+ priority: priority , isChildTask : false , copyTaskLocals : true ,
481
+ inheritContext: true , enqueueJob : true ,
482
+ addPendingGroupTaskUnconditionally : false
483
+ )
557
484
558
485
// Create the asynchronous task future.
559
- let ( task, _) = Builtin . createAsyncTask ( Int ( flags. bits ) , operation)
486
+ let ( task, _) = Builtin . createAsyncTask ( flags, operation)
560
487
561
488
self . _task = task
562
489
#else
@@ -599,18 +526,20 @@ extension Task where Failure == Never {
599
526
/// tasks result or `cancel` it. If the operation fails the handle will
600
527
/// throw the error the operation has thrown when awaited on.
601
528
@discardableResult
529
+ @_alwaysEmitIntoClient
602
530
public static func detached(
603
531
priority: TaskPriority ? = nil ,
604
532
operation: __owned @Sendable @escaping ( ) async -> Success
605
533
) -> Task < Success , Failure > {
606
534
#if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
607
535
// Set up the job flags for a new task.
608
- var flags = TaskCreateFlags ( )
609
- flags. priority = priority
610
- flags. enqueueJob = true
536
+ let flags = taskCreateFlags (
537
+ priority: priority, isChildTask: false , copyTaskLocals: false ,
538
+ inheritContext: false , enqueueJob: true ,
539
+ addPendingGroupTaskUnconditionally: false )
611
540
612
541
// Create the asynchronous task future.
613
- let ( task, _) = Builtin . createAsyncTask ( Int ( flags. bits ) , operation)
542
+ let ( task, _) = Builtin . createAsyncTask ( flags, operation)
614
543
615
544
return Task ( task)
616
545
#else
@@ -654,18 +583,21 @@ extension Task where Failure == Error {
654
583
/// tasks result or `cancel` it. If the operation fails the handle will
655
584
/// throw the error the operation has thrown when awaited on.
656
585
@discardableResult
586
+ @_alwaysEmitIntoClient
657
587
public static func detached(
658
588
priority: TaskPriority ? = nil ,
659
589
operation: __owned @Sendable @escaping ( ) async throws -> Success
660
590
) -> Task < Success , Failure > {
661
591
#if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
662
592
// Set up the job flags for a new task.
663
- var flags = TaskCreateFlags ( )
664
- flags. priority = priority
665
- flags. enqueueJob = true
593
+ let flags = taskCreateFlags (
594
+ priority: priority, isChildTask: false , copyTaskLocals: false ,
595
+ inheritContext: false , enqueueJob: true ,
596
+ addPendingGroupTaskUnconditionally: false
597
+ )
666
598
667
599
// Create the asynchronous task future.
668
- let ( task, _) = Builtin . createAsyncTask ( Int ( flags. bits ) , operation)
600
+ let ( task, _) = Builtin . createAsyncTask ( flags, operation)
669
601
670
602
return Task ( task)
671
603
#else
0 commit comments