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>
This commit is contained in:
arctic-alpaca 2025-04-03 11:02:44 +02:00 committed by GitHub
parent 0030d609a4
commit 03db672b8f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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 @@ BaseType_t xPortStartScheduler( void )
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 );