Skip to content

Fix timeout reporting and mutex leak in event_wait_timed - #1525

Open
TedLyngmo wants to merge 1 commit into
FreeRTOS:mainfrom
TedLyngmo:fix_event_wait_timed
Open

TedLyngmo wants to merge 1 commit into
FreeRTOS:mainfrom
TedLyngmo:fix_event_wait_timed

Conversation

@TedLyngmo

@TedLyngmo TedLyngmo commented Oct 23, 2026 •

Copy link
Copy Markdown

Fix timeout reporting and mutex leak in event_wait_timed

pthread_cond_timedwait returns the error number directly rather than returning -1 and setting errno, so the check for ( ret == -1 ) && ( errno == ETIMEDOUT ) was never true. On timeout the loop still exited via the ( ret == 0 ) condition, but the function then always returned true, so a timeout was wrongly reported as success. Had the intended branch fired, it would also have leaked the held mutex.

Check ret == ETIMEDOUT and break out of the wait loop so all paths reach the single unlock. Return the actual event_triggered state read under the mutex instead of a hardcoded true, which also reports the correct result when a signal races with the timeout.

Test Steps

This program failes without this patch:

/* cc -D_GNU_SOURCE t.c wait_for_event.c -lpthread && ./a.out */
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include "wait_for_event.h"

static void * sig( void * ev )
{
    usleep( 50000 );
    event_signal( ev );
    return NULL;
}

int main( void )
{
    struct event * ev = event_create();
    pthread_t th;

    /* Timeout must report false, and must not leak the mutex. */
    assert( event_wait_timed( ev, 100 ) == false );

    /* Object still usable after timeout; signal must report true. */
    pthread_create( &th, NULL, sig, ev );
    assert( event_wait_timed( ev, 5000 ) == true );
    pthread_join( th, NULL );

    event_delete( ev );
    puts( "OK" );
    return 0;
}

Checklist:

  • I have tested my changes. No regression in existing tests.
  • I have modified and/or added unit-tests to cover the code changes in this Pull Request.

Related Issue

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

pthread_cond_timedwait returns the error number directly rather than
returning -1 and setting errno, so the check for ( ret == -1 ) &&
( errno == ETIMEDOUT ) was never true. On timeout the loop still
exited via the ( ret == 0 ) condition, but the function then always
returned true, so a timeout was wrongly reported as success. Had the
intended branch fired, it would also have leaked the held mutex.

Check ret == ETIMEDOUT and break out of the wait loop so all paths
reach the single unlock. Return the actual event_triggered state read
under the mutex instead of a hardcoded true, which also reports the
correct result when a signal races with the timeout.

Signed-off-by: Ted Lyngmo <ted@lyncon.se>
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant