Fix race in POSIX port `vPortEndScheduler` (#1262)

* Fix race in POSIX port `vPortEndScheduler`

The `vPortEndScheduler` checks whether it's a FreeRTOS thread after signalling the scheduler thread to stop. This creates a race between the check and the destruction of the thread key. By moving the signal to the scheduler thread after the check, the race is prevented.

* Code review suggestions

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

---------

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c
index dd7ca1a..b5a4a1b 100644
--- a/portable/ThirdParty/GCC/Posix/port.c
+++ b/portable/ThirdParty/GCC/Posix/port.c
@@ -48,8 +48,8 @@
 * stdio (printf() and friends) should be called from a single task
 * only or serialized with a FreeRTOS primitive such as a binary
 * semaphore or mutex.
-* 
-* Note: When using LLDB (the default debugger on macOS) with this port, 
+*
+* Note: When using LLDB (the default debugger on macOS) with this port,
 * suppress SIGUSR1 to prevent debugger interference. This can be
 * done by adding the following line to ~/.lldbinit:
 * `process handle SIGUSR1 -n true -p false -s false`
@@ -324,17 +324,23 @@
 void vPortEndScheduler( void )
 {
     Thread_t * pxCurrentThread;
+    BaseType_t xIsFreeRTOSThread;
 
     /* Stop the timer tick thread. */
     xTimerTickThreadShouldRun = false;
     pthread_join( hTimerTickThread, NULL );
 
+    /* Check whether the current thread is a FreeRTOS thread.
+     * This has to happen before the scheduler is signaled to exit
+     * its loop to prevent data races on the thread key. */
+    xIsFreeRTOSThread = prvIsFreeRTOSThread();
+
     /* Signal the scheduler to exit its loop. */
     xSchedulerEnd = pdTRUE;
     ( void ) pthread_kill( hMainThread, SIG_RESUME );
 
     /* Waiting to be deleted here. */
-    if( prvIsFreeRTOSThread() == pdTRUE )
+    if( xIsFreeRTOSThread == pdTRUE )
     {
         pxCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
         event_wait( pxCurrentThread->ev );