@@ -379,15 +379,6 @@ bool swift_bincompat_useLegacyNonCrashingExecutorChecks() {
379379 return legacyMode;
380380}
381381
382- // Check override of executor checking mode.
383- static void checkIsCurrentExecutorMode (void *context) {
384- bool useLegacyMode =
385- swift_bincompat_useLegacyNonCrashingExecutorChecks ();
386- auto checkMode = static_cast <IsCurrentExecutorCheckMode *>(context);
387- *checkMode = useLegacyMode ? Legacy_NoCheckIsolated_NonCrashing
388- : Swift6_UseCheckIsolated_AllowCrash;
389- }
390-
391382// Implemented in Swift to avoid some annoying hard-coding about
392383// TaskExecutor's protocol witness table. We could inline this
393384// with effort, though.
@@ -402,9 +393,16 @@ extern "C" SWIFT_CC(swift) void _swift_task_enqueueOnExecutor(
402393 Job *job, HeapObject *executor, const Metadata *executorType,
403394 const SerialExecutorWitnessTable *wtable);
404395
396+ namespace {
397+ using SwiftTaskIsCurrentExecutorOptions =
398+ OptionSet<swift_task_is_current_executor_flag>;
399+ }
400+
405401SWIFT_CC (swift)
406- static bool isCurrentExecutor (SerialExecutorRef expectedExecutor,
407- IsCurrentExecutorCheckMode checkMode) {
402+ static bool swift_task_isCurrentExecutorWithFlagsImpl (
403+ SerialExecutorRef expectedExecutor,
404+ swift_task_is_current_executor_flag flags) {
405+ auto options = SwiftTaskIsCurrentExecutorOptions (flags);
408406 auto current = ExecutorTrackingInfo::current ();
409407
410408 if (!current) {
@@ -423,14 +421,14 @@ static bool isCurrentExecutor(SerialExecutorRef expectedExecutor,
423421
424422 // Otherwise, as last resort, let the expected executor check using
425423 // external means, as it may "know" this thread is managed by it etc.
426- if (checkMode == Swift6_UseCheckIsolated_AllowCrash ) {
424+ if (options. contains (swift_task_is_current_executor_flag::Assert) ) {
427425 swift_task_checkIsolated (expectedExecutor); // will crash if not same context
428426
429427 // checkIsolated did not crash, so we are on the right executor, after all!
430428 return true ;
431429 }
432430
433- assert (checkMode == Legacy_NoCheckIsolated_NonCrashing );
431+ assert (!options. contains (swift_task_is_current_executor_flag::Assert) );
434432 return false ;
435433 }
436434
@@ -461,7 +459,7 @@ static bool isCurrentExecutor(SerialExecutorRef expectedExecutor,
461459 // the crashing 'dispatch_assert_queue(main queue)' which will either crash
462460 // or confirm we actually are on the main queue; or the custom expected
463461 // executor has a chance to implement a similar queue check.
464- if (checkMode == Legacy_NoCheckIsolated_NonCrashing ) {
462+ if (!options. contains (swift_task_is_current_executor_flag::Assert) ) {
465463 if ((expectedExecutor.isMainExecutor () && !currentExecutor.isMainExecutor ()) ||
466464 (!expectedExecutor.isMainExecutor () && currentExecutor.isMainExecutor ())) {
467465 return false ;
@@ -522,7 +520,7 @@ static bool isCurrentExecutor(SerialExecutorRef expectedExecutor,
522520 // Note that this only works because the closure in assumeIsolated is
523521 // synchronous, and will not cause suspensions, as that would require the
524522 // presence of a Task.
525- if (checkMode == Swift6_UseCheckIsolated_AllowCrash ) {
523+ if (options. contains (swift_task_is_current_executor_flag::Assert) ) {
526524 swift_task_checkIsolated (expectedExecutor); // will crash if not same context
527525
528526 // The checkIsolated call did not crash, so we are on the right executor.
@@ -531,10 +529,20 @@ static bool isCurrentExecutor(SerialExecutorRef expectedExecutor,
531529
532530 // In the end, since 'checkIsolated' could not be used, so we must assume
533531 // that the executors are not the same context.
534- assert (checkMode == Legacy_NoCheckIsolated_NonCrashing );
532+ assert (!options. contains (swift_task_is_current_executor_flag::Assert) );
535533 return false ;
536534}
537535
536+ // Check override of executor checking mode.
537+ static void swift_task_setDefaultExecutorCheckingFlags (void *context) {
538+ bool useLegacyMode = swift_bincompat_useLegacyNonCrashingExecutorChecks ();
539+ auto checkMode = static_cast <swift_task_is_current_executor_flag *>(context);
540+ if (!useLegacyMode) {
541+ *checkMode = swift_task_is_current_executor_flag (
542+ *checkMode | swift_task_is_current_executor_flag::Assert);
543+ }
544+ }
545+
538546SWIFT_CC (swift)
539547static bool
540548swift_task_isCurrentExecutorImpl (SerialExecutorRef expectedExecutor) {
@@ -546,11 +554,14 @@ swift_task_isCurrentExecutorImpl(SerialExecutorRef expectedExecutor) {
546554 // instead must call into 'checkIsolated' or crash directly.
547555 //
548556 // Whenever we confirm an executor equality, we can return true, in any mode.
549- static IsCurrentExecutorCheckMode checkMode;
550- static swift::once_t checkModeToken;
551- swift::once (checkModeToken, checkIsCurrentExecutorMode, &checkMode);
557+ static swift_task_is_current_executor_flag isCurrentExecutorFlag;
558+ static swift::once_t isCurrentExecutorFlagToken;
559+ swift::once (isCurrentExecutorFlagToken,
560+ swift_task_setDefaultExecutorCheckingFlags,
561+ &isCurrentExecutorFlag);
552562
553- return isCurrentExecutor (expectedExecutor, checkMode);
563+ return swift_task_isCurrentExecutorWithFlags (expectedExecutor,
564+ isCurrentExecutorFlag);
554565}
555566
556567// / Logging level for unexpected executors:
@@ -2337,11 +2348,8 @@ static void swift_task_deinitOnExecutorImpl(void *object,
23372348 //
23382349 // Note that isCurrentExecutor() returns true for @MainActor
23392350 // when running on the main thread without any executor.
2340- //
2341- // We always use "legacy" checking mode here, because that's the desired
2342- // behaviour for this use case. This does not change with SDK version or
2343- // language mode.
2344- if (isCurrentExecutor (newExecutor, Legacy_NoCheckIsolated_NonCrashing)) {
2351+ if (swift_task_isCurrentExecutorWithFlags (
2352+ newExecutor, swift_task_is_current_executor_flag::None)) {
23452353 return work (object); // 'return' forces tail call
23462354 }
23472355
0 commit comments