@@ -374,6 +374,12 @@ static bool swift_task_isCurrentExecutorImpl(SerialExecutorRef expectedExecutor)
374
374
375
375
// To support old applications on apple platforms which assumed this call
376
376
// does not crash, try to use a more compatible mode for those apps.
377
+ //
378
+ // We only allow returning `false` directly from this function when operating
379
+ // in 'Legacy_NoCheckIsolated_NonCrashing' mode. If allowing crashes, we
380
+ // instead must call into 'checkIsolated' or crash directly.
381
+ //
382
+ // Whenever we confirm an executor equality, we can return true, in any mode.
377
383
static swift::once_t checkModeToken;
378
384
swift::once (checkModeToken, checkIsCurrentExecutorMode, nullptr );
379
385
@@ -425,40 +431,47 @@ static bool swift_task_isCurrentExecutorImpl(SerialExecutorRef expectedExecutor)
425
431
// If the expected executor is a default actor, it makes no sense to try
426
432
// the 'checkIsolated' call, it must be equal to the other actor, or it is
427
433
// not the same isolation domain.
428
- swift_Concurrency_fatalError (0 , " Incorrect actor executor assumption" );
434
+ if (isCurrentExecutorMode == Default_UseCheckIsolated_AllowCrash) {
435
+ swift_Concurrency_fatalError (0 , " Incorrect actor executor assumption" );
436
+ }
429
437
return false ;
430
438
}
431
439
432
440
if (expectedExecutor.isMainExecutor () && !currentExecutor.isMainExecutor ()) {
433
- // TODO: Invoke checkIsolated() on "main" SerialQueue once it implements `checkIsolated`, otherwise messages will be sub-par and hard to address
434
- swift_Concurrency_fatalError (0 , " Incorrect actor executor assumption; Expected MainActor executor" );
441
+ if (isCurrentExecutorMode == Default_UseCheckIsolated_AllowCrash) {
442
+ // TODO: Invoke checkIsolated() on "main" SerialQueue once it implements `checkIsolated`, for potentially better/more consistent error messages
443
+ swift_Concurrency_fatalError (0 , " Incorrect actor executor assumption; Expected MainActor executor" );
444
+ }
435
445
return false ;
436
446
} else if (!expectedExecutor.isMainExecutor () && currentExecutor.isMainExecutor ()) {
437
- // TODO: Invoke checkIsolated() on "main" SerialQueue once it implements `checkIsolated`, otherwise messages will be sub-par and hard to address
438
- swift_Concurrency_fatalError (0 , " Incorrect actor executor assumption; Expected not-MainActor executor" );
447
+ if (isCurrentExecutorMode == Default_UseCheckIsolated_AllowCrash) {
448
+ // TODO: Invoke checkIsolated() on "main" SerialQueue once it implements `checkIsolated`, for potentially better/more consistent error messages
449
+ swift_Concurrency_fatalError (0 , " Incorrect actor executor assumption; Expected not-MainActor executor" );
450
+ }
439
451
return false ;
440
452
}
441
453
442
454
if (expectedExecutor.isComplexEquality ()) {
443
- if (!swift_compareWitnessTables (
444
- reinterpret_cast <const WitnessTable*>(currentExecutor.getSerialExecutorWitnessTable ()),
445
- reinterpret_cast <const WitnessTable*>(expectedExecutor.getSerialExecutorWitnessTable ()))) {
446
- // different witness table, we cannot invoke complex equality call
447
- return false ;
448
- }
449
-
450
- // Avoid passing nulls to Swift for the isSame check:
451
- if (!currentExecutor.getIdentity () || !expectedExecutor.getIdentity ()) {
452
- return false ;
455
+ if (currentExecutor.getIdentity () && expectedExecutor.getIdentity () &&
456
+ swift_compareWitnessTables (
457
+ reinterpret_cast <const WitnessTable *>(
458
+ currentExecutor.getSerialExecutorWitnessTable ()),
459
+ reinterpret_cast <const WitnessTable *>(
460
+ expectedExecutor.getSerialExecutorWitnessTable ()))) {
461
+
462
+ auto isSameExclusiveExecutionContextResult =
463
+ _task_serialExecutor_isSameExclusiveExecutionContext (
464
+ currentExecutor.getIdentity (), expectedExecutor.getIdentity (),
465
+ swift_getObjectType (currentExecutor.getIdentity ()),
466
+ expectedExecutor.getSerialExecutorWitnessTable ());
467
+
468
+ // if the 'isSameExclusiveExecutionContext' returned true we trust
469
+ // it and return; if it was false, we need to give checkIsolated another
470
+ // chance to check.
471
+ if (isSameExclusiveExecutionContextResult) {
472
+ return true ;
473
+ }
453
474
}
454
-
455
- auto result = _task_serialExecutor_isSameExclusiveExecutionContext (
456
- currentExecutor.getIdentity (),
457
- expectedExecutor.getIdentity (),
458
- swift_getObjectType (currentExecutor.getIdentity ()),
459
- expectedExecutor.getSerialExecutorWitnessTable ());
460
-
461
- return result;
462
475
}
463
476
464
477
// This provides a last-resort check by giving the expected SerialExecutor the
@@ -488,7 +501,6 @@ static bool swift_task_isCurrentExecutorImpl(SerialExecutorRef expectedExecutor)
488
501
return true ;
489
502
}
490
503
491
- // Using legacy mode, if no explicit executor match worked, we assume `false`
492
504
assert (isCurrentExecutorMode == Legacy_NoCheckIsolated_NonCrashing);
493
505
return false ;
494
506
}
0 commit comments