Ignore:
Timestamp:
May 10, 2023, 2:46:05 PM (16 months ago)
Author:
caparsons <caparson@…>
Branches:
ADT, ast-experimental, master
Children:
8fd1b7c
Parents:
e50fce1
Message:

Added fix for cond var timeout handling race. Cleanup of locks.hfa/cfa changes is an ongoing TODO

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/locks.cfa

    re50fce1 rfece3d9  
    171171}
    172172
    173 size_t on_wait( blocking_lock & this ) with( this ) {
     173size_t on_wait( blocking_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) with( this ) {
    174174        lock( lock __cfaabi_dbg_ctx2 );
    175175        /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );
     
    184184        unlock( lock );
    185185
    186     park();
     186    pre_park_then_park( pp_fn, pp_datum );
    187187
    188188        return ret;
     
    396396        }
    397397
    398     static size_t block_and_get_recursion( info_thread(L) & i ) {
     398    static size_t block_and_get_recursion( info_thread(L) & i, __cfa_pre_park pp_fn, void * pp_datum ) {
    399399        size_t recursion_count = 0;
    400400                if ( i.lock ) {
    401401                        // if lock was passed get recursion count to reset to after waking thread
    402                         recursion_count = on_wait( *i.lock ); // this call blocks
    403                 } else park( );
     402                        recursion_count = on_wait( *i.lock, pp_fn, pp_datum ); // this call blocks
     403                } else pre_park_then_park( pp_fn, pp_datum );
    404404        return recursion_count;
    405405    }
     406    static size_t block_and_get_recursion( info_thread(L) & i ) { return block_and_get_recursion( i, pre_park_noop, 0p ); }
    406407
    407408        // helper for wait()'s' with no timeout
     
    424425                queue_info_thread( this, i );
    425426
     427    static void cond_alarm_register( void * node_ptr ) { register_self( (alarm_node_t *)node_ptr ); }
     428
    426429        // helper for wait()'s' with a timeout
    427430        static void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) {
     
    433436
    434437                // registers alarm outside cond lock to avoid deadlock
    435                 register_self( &node_wrap.alarm_node );
     438                // register_self( &node_wrap.alarm_node );
    436439
    437440                // blocks here
    438         size_t recursion_count = block_and_get_recursion( info );
     441        size_t recursion_count = block_and_get_recursion( info, cond_alarm_register, (void *)(&node_wrap.alarm_node) );
    439442                // park();
    440443
     
    503506                info_thread( L ) i = { active_thread(), info, &l };
    504507                insert_last( blocked_threads, i );
    505                 size_t recursion_count = on_wait( *i.lock ); // blocks here
     508                size_t recursion_count = on_wait( *i.lock, pre_park_noop, 0p ); // blocks here
    506509                // park( );
    507510                on_wakeup(*i.lock, recursion_count);
     
    552555        //      return recursion_count;
    553556        // }
    554 
    555557       
    556558        static void queue_info_thread_timeout( pthread_cond_var(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) {
     
    562564
    563565                // registers alarm outside cond lock to avoid deadlock
    564                 register_self( &node_wrap.alarm_node );
     566                // register_self( &node_wrap.alarm_node ); // C_TODO: fix race: registers itself and then alarm handler calls on_notify before block_and_get_recursion is run
    565567
    566568                // blocks here
    567         size_t recursion_count = block_and_get_recursion( info );
     569        size_t recursion_count = block_and_get_recursion( info, cond_alarm_register, (void *)(&node_wrap.alarm_node) );
    568570                // park();
    569571
Note: See TracChangeset for help on using the changeset viewer.