@@ -337,33 +337,47 @@ static IsCurrentExecutorCheckMode isCurrentExecutorMode =
337
337
338
338
339
339
// Shimming call to Swift runtime because Swift Embedded does not have
340
- // these symbols defined
340
+ // these symbols defined.
341
341
bool swift_bincompat_useLegacyNonCrashingExecutorChecks () {
342
342
#if !SWIFT_CONCURRENCY_EMBEDDED
343
343
return swift::runtime::bincompat::
344
344
swift_bincompat_useLegacyNonCrashingExecutorChecks ();
345
- #endif
345
+ #else
346
346
return false ;
347
+ #endif
347
348
}
348
349
349
350
// Check override of executor checking mode.
350
351
static void checkIsCurrentExecutorMode (void *context) {
351
352
auto useLegacyMode =
352
353
swift_bincompat_useLegacyNonCrashingExecutorChecks ();
353
354
355
+ fprintf (stderr, " [%s:%d](%s) useLegacyMode FROM BINCOMPAT = %s\n " , __FILE_NAME__, __LINE__, __FUNCTION__,
356
+ useLegacyMode ? " Legacy_NoCheckIsolated_NonCrashing" : " Default_UseCheckIsolated_AllowCrash" );
357
+
354
358
// Potentially, override the platform detected mode, primarily used in tests.
355
359
#if SWIFT_STDLIB_HAS_ENVIRON
356
- if (const char *modeStr =
357
- runtime::environment::concurrencyIsCurrentExecutorLegacyModeOverride ()) {
358
- if (modeStr) {
359
- if (strcmp (modeStr, " nocrash" ) == 0 ) {
360
- useLegacyMode = true ;
361
- } else if (strcmp (modeStr, " crash" ) == 0 ) {
362
- useLegacyMode = false ;
363
- } // else, just use the platform detected mode
364
- }
360
+ // if (const char *modeStr = runtime::environment::concurrencyIsCurrentExecutorLegacyModeOverride()) {
361
+ if (const char *modeStr = getenv (" SWIFT_IS_CURRENT_EXECUTOR_LEGACY_MODE_OVERRIDE" )) {
362
+ if (strcmp (modeStr, " nocrash" ) == 0 || strcmp (modeStr, " legacy" ) == 0 ) {
363
+ fprintf (stderr, " [%s:%d](%s) OVERRIDE TO USE [LEGACY] MODE\n " , __FILE_NAME__, __LINE__, __FUNCTION__);
364
+ useLegacyMode = true ;
365
+ } else if (strcmp (modeStr, " crash" ) == 0 || strcmp (modeStr, " swift6" ) == 0 ) {
366
+ fprintf (stderr, " [%s:%d](%s) OVERRIDE TO USE [CRASH] MODE\n " , __FILE_NAME__, __LINE__, __FUNCTION__);
367
+ useLegacyMode = false ;
368
+ } // else, just use the platform detected mode
369
+
370
+ fprintf (stderr, " [%s:%d](%s) useLegacyMode override from ENV = %s (mode string = %s)\n " ,
371
+ __FILE_NAME__, __LINE__, __FUNCTION__,
372
+ useLegacyMode ? " Legacy_NoCheckIsolated_NonCrashing"
373
+ : " Default_UseCheckIsolated_AllowCrash" ,
374
+ modeStr);
375
+ } else {
376
+ fprintf (stderr, " [%s:%d](%s) no override of useLegacyMode...\n " ,
377
+ __FILE_NAME__, __LINE__, __FUNCTION__);
365
378
}
366
379
#endif // SWIFT_STDLIB_HAS_ENVIRON
380
+
367
381
isCurrentExecutorMode = useLegacyMode ? Legacy_NoCheckIsolated_NonCrashing
368
382
: Default_UseCheckIsolated_AllowCrash;
369
383
}
@@ -383,14 +397,27 @@ static bool swift_task_isCurrentExecutorImpl(SerialExecutorRef expectedExecutor)
383
397
static swift::once_t checkModeToken;
384
398
swift::once (checkModeToken, checkIsCurrentExecutorMode, nullptr );
385
399
400
+ auto modeString = isCurrentExecutorMode == Legacy_NoCheckIsolated_NonCrashing
401
+ ? " Legacy_NoCheckIsolated_NonCrashing"
402
+ : " Default_UseCheckIsolated_AllowCrash" ;
403
+ fprintf (stderr, " [%s:%d](%s) MODE = isCurrentExecutorMode = %s\n " , __FILE_NAME__, __LINE__, __FUNCTION__,
404
+ modeString);
405
+
406
+ fprintf (stderr, " [%s:%d](%s) expected executor is main: %d\n " , __FILE_NAME__, __LINE__, __FUNCTION__,
407
+ expectedExecutor.isMainExecutor ());
408
+ fprintf (stderr, " [%s:%d](%s) thread is main: %d\n " , __FILE_NAME__, __LINE__, __FUNCTION__,
409
+ isExecutingOnMainThread ());
410
+
386
411
if (!current) {
412
+ fprintf (stderr, " [%s:%d](%s) no current\n " , __FILE_NAME__, __LINE__, __FUNCTION__);
387
413
// We have no current executor, i.e. we are running "outside" of Swift
388
414
// Concurrency. We could still be running on a thread/queue owned by
389
415
// the expected executor however, so we need to try a bit harder before
390
416
// we fail.
391
417
392
418
// Are we expecting the main executor and are using the main thread?
393
419
if (expectedExecutor.isMainExecutor () && isExecutingOnMainThread ()) {
420
+ fprintf (stderr, " [%s:%d](%s) main executor; main thread >>>>> true\n " , __FILE_NAME__, __LINE__, __FUNCTION__);
394
421
// Due to compatibility with pre-checkIsolated code, we cannot remove
395
422
// this special handling. CheckIsolated can handle this if the expected
396
423
// executor is the main queue / main executor, however, if we cannot call
@@ -399,15 +426,23 @@ static bool swift_task_isCurrentExecutorImpl(SerialExecutorRef expectedExecutor)
399
426
return true ;
400
427
}
401
428
429
+ fprintf (stderr, " [%s:%d](%s) have current executor = %p\n " , __FILE_NAME__, __LINE__, __FUNCTION__,
430
+ current);
431
+
402
432
// Otherwise, as last resort, let the expected executor check using
403
433
// external means, as it may "know" this thread is managed by it etc.
404
434
if (isCurrentExecutorMode == Default_UseCheckIsolated_AllowCrash) {
435
+ fprintf (stderr, " [%s:%d](%s) allow crash mode, checkIsolated call \n " , __FILE_NAME__, __LINE__, __FUNCTION__);
405
436
swift_task_checkIsolated (expectedExecutor);
406
437
// checkIsolated did not crash, so we are on the right executor, after all!
438
+ fprintf (stderr, " [%s:%d](%s) checkIsolated call passed >>>>> true\n " , __FILE_NAME__, __LINE__, __FUNCTION__);
407
439
return true ;
440
+ } else {
441
+ fprintf (stderr, " [%s:%d](%s) cannot invoke 'checkIsolated'\n " , __FILE_NAME__, __LINE__, __FUNCTION__);
408
442
}
409
443
410
444
assert (isCurrentExecutorMode == Legacy_NoCheckIsolated_NonCrashing);
445
+ fprintf (stderr, " [%s:%d](%s) >>>>> false\n " , __FILE_NAME__, __LINE__, __FUNCTION__);
411
446
return false ;
412
447
}
413
448
@@ -417,39 +452,43 @@ static bool swift_task_isCurrentExecutorImpl(SerialExecutorRef expectedExecutor)
417
452
// We assume executors do not come-and-go appearing under the same address,
418
453
// and treat pointer equality of executors as good enough to assume the executor.
419
454
if (currentExecutor == expectedExecutor) {
455
+ fprintf (stderr, " [%s:%d](%s) executor pointer equal; >>>>> true\n " , __FILE_NAME__, __LINE__, __FUNCTION__);
420
456
return true ;
421
457
}
422
458
423
459
// Fast-path, specialize the common case of comparing two main executors.
424
460
if (currentExecutor.isMainExecutor () && expectedExecutor.isMainExecutor ()) {
461
+ fprintf (stderr, " [%s:%d](%s) both are main executor >>>>> true\n " , __FILE_NAME__, __LINE__, __FUNCTION__);
425
462
return true ;
426
463
}
427
464
428
- // If the expected executor is "default" then we should have matched
429
- // by pointer equality already with the current executor.
430
- if (expectedExecutor.isDefaultActor ()) {
431
- // If the expected executor is a default actor, it makes no sense to try
432
- // the 'checkIsolated' call, it must be equal to the other actor, or it is
433
- // not the same isolation domain.
434
- if (isCurrentExecutorMode == Default_UseCheckIsolated_AllowCrash) {
435
- swift_Concurrency_fatalError (0 , " Incorrect actor executor assumption" );
436
- }
437
- return false ;
438
- }
439
-
440
- if (expectedExecutor.isMainExecutor () && !currentExecutor.isMainExecutor ()) {
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
- }
445
- return false ;
446
- } else if (!expectedExecutor.isMainExecutor () && currentExecutor.isMainExecutor ()) {
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
- }
451
- return false ;
452
- }
465
+ // FIXME: this was incorrect, if expected is default we need to invoke the checkIsolated
466
+ // // If the expected executor is "default" then we should have matched
467
+ // // by pointer equality already with the current executor.
468
+ // if (expectedExecutor.isDefaultActor()) {
469
+ // // If the expected executor is a default actor, it makes no sense to try
470
+ // // the 'checkIsolated' call, it must be equal to the other actor, or it is
471
+ // // not the same isolation domain.
472
+ // fprintf(stderr, "[%s:%d](%s) both are main executor >>>>> true\n", __FILE_NAME__, __LINE__, __FUNCTION__);
473
+ // if (isCurrentExecutorMode == Default_UseCheckIsolated_AllowCrash) {
474
+ // swift_Concurrency_fatalError(0, "Incorrect actor executor assumption");
475
+ // }
476
+ // return false;
477
+ // }
478
+
479
+ // FIXME: all of this is wrong, we need to keep trying complex equality;
480
+ // as something may not be EQUAL to the main executor but still be equivalent to it.
481
+ // if (expectedExecutor.isMainExecutor() && !currentExecutor.isMainExecutor()) {
482
+ // if (isCurrentExecutorMode == Default_UseCheckIsolated_AllowCrash) {
483
+ // swift_Concurrency_fatalError(0, "Incorrect actor executor assumption; Expected MainActor executor");
484
+ // }
485
+ // return false;
486
+ // } else if (!expectedExecutor.isMainExecutor() && currentExecutor.isMainExecutor()) {
487
+ // if (isCurrentExecutorMode == Default_UseCheckIsolated_AllowCrash) {
488
+ // swift_Concurrency_fatalError(0, "Incorrect actor executor assumption; Expected not-MainActor executor");
489
+ // }
490
+ // return false;
491
+ // }
453
492
454
493
if (expectedExecutor.isComplexEquality ()) {
455
494
if (currentExecutor.getIdentity () && expectedExecutor.getIdentity () &&
@@ -469,6 +508,7 @@ static bool swift_task_isCurrentExecutorImpl(SerialExecutorRef expectedExecutor)
469
508
// it and return; if it was false, we need to give checkIsolated another
470
509
// chance to check.
471
510
if (isSameExclusiveExecutionContextResult) {
511
+ fprintf (stderr, " [%s:%d](%s) is same exclusive execution context! >>>> true\n " , __FILE_NAME__, __LINE__, __FUNCTION__);
472
512
return true ;
473
513
}
474
514
}
@@ -496,12 +536,15 @@ static bool swift_task_isCurrentExecutorImpl(SerialExecutorRef expectedExecutor)
496
536
// presence of a Task.
497
537
// compat_invoke_swift_task_checkIsolated(expectedExecutor);
498
538
if (isCurrentExecutorMode == Default_UseCheckIsolated_AllowCrash) {
539
+ fprintf (stderr, " [%s:%d](%s) last chance; invoke 'checkIsolated'\n " , __FILE_NAME__, __LINE__, __FUNCTION__);
499
540
swift_task_checkIsolated (expectedExecutor);
541
+
500
542
// The checkIsolated call did not crash, so we are on the right executor.
543
+ fprintf (stderr, " [%s:%d](%s) checkIsolated did not crash; >>>>>> true\n " , __FILE_NAME__, __LINE__, __FUNCTION__);
501
544
return true ;
502
545
}
503
546
504
- assert (isCurrentExecutorMode == Legacy_NoCheckIsolated_NonCrashing );
547
+ fprintf (stderr, " [%s:%d](%s) cannot invoke 'checkIsolated' assume not equal >>>>>> false \n " , __FILE_NAME__, __LINE__, __FUNCTION__ );
505
548
return false ;
506
549
}
507
550
@@ -524,9 +567,30 @@ static void checkUnexpectedExecutorLogLevel(void *context) {
524
567
if (!levelStr)
525
568
return ;
526
569
570
+ auto isSameExecutorLegacyMode =
571
+ swift_bincompat_useLegacyNonCrashingExecutorChecks ();
572
+
527
573
long level = strtol (levelStr, nullptr , 0 );
528
- if (level >= 0 && level < 3 )
529
- unexpectedExecutorLogLevel = level;
574
+ if (level >= 0 && level < 3 ) {
575
+ if (isSameExecutorLegacyMode) {
576
+ // legacy mode permits doing nothing or just logging, since the method
577
+ // used to perform the check itself is not going to crash:
578
+ unexpectedExecutorLogLevel = level;
579
+ } else {
580
+ // We are in swift6/crash mode of isSameExecutor... which means that
581
+ // rather than returning false, that method will always CRASH when an
582
+ // executor mismatch is discovered. This means that it is not possible
583
+ // to support logging or warning 'unexpected executor log level' in this mode.
584
+ if (level > 1 ) {
585
+ fprintf (stderr, " [%s:%d](%s) [unexpected executor] ONLY CRASH MODE IS OK\n " , __FILE_NAME__, __LINE__, __FUNCTION__);
586
+ unexpectedExecutorLogLevel = level;
587
+ } else {
588
+ fprintf (stderr,
589
+ " [%s:%d](%s) [unexpected executor] HAD TO IGNORE LEVEL [%s] CRASH MODE IS OK\n " ,
590
+ level, __FILE_NAME__, __LINE__, __FUNCTION__);
591
+ }
592
+ }
593
+ }
530
594
#endif // SWIFT_STDLIB_HAS_ENVIRON
531
595
}
532
596
0 commit comments