Changeset b93bf85


Ignore:
Timestamp:
Jul 11, 2023, 2:27:58 PM (10 months ago)
Author:
caparsons <caparson@…>
Branches:
master
Children:
bbecdd4
Parents:
4c8ce47
Message:

fixed spurious channel close waituntil error case. Was caused by a race condition causing an exception to be thrown while another was in flight

Files:
9 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/channel.hfa

    r4c8ce47 rb93bf85  
    444444}
    445445static inline bool unregister_select( chan_read(T) & this, select_node & node ) { return unregister_chan( this.chan, node ); }
    446 static inline void on_selected( chan_read(T) & this, select_node & node ) with(this) {
    447     if ( node.extra == 0p ) // check if woken up due to closed channel
    448         __closed_remove( chan, ret );
     446static inline bool on_selected( chan_read(T) & this, select_node & node ) with(this) {
     447    if ( unlikely(node.extra == 0p) ) {
     448        if ( !exception_in_flight() ) __closed_remove( chan, ret ); // check if woken up due to closed channel
     449        else return false;
     450    }
    449451    // This is only reachable if not closed or closed exception was handled
     452    return true;
    450453}
    451454
     
    536539static inline bool unregister_select( chan_write(T) & this, select_node & node ) { return unregister_chan( this.chan, node ); }
    537540
    538 static inline void on_selected( chan_write(T) & this, select_node & node ) with(this) {
    539     if ( node.extra == 0p ) // check if woken up due to closed channel
    540         __closed_insert( chan, elem );
    541 
     541static inline bool on_selected( chan_write(T) & this, select_node & node ) with(this) {
     542    if ( unlikely(node.extra == 0p) ) {
     543        if ( !exception_in_flight() ) __closed_insert( chan, elem ); // check if woken up due to closed channel
     544        else return false;
     545    }
    542546    // This is only reachable if not closed or closed exception was handled
     547    return true;
    543548}
    544549
  • libcfa/src/concurrency/future.hfa

    r4c8ce47 rb93bf85  
    180180        }
    181181               
    182         void on_selected( future(T) & this, select_node & node ) {}
     182        bool on_selected( future(T) & this, select_node & node ) { return true; }
    183183        }
    184184}
  • libcfa/src/concurrency/invoke.h

    r4c8ce47 rb93bf85  
    255255        #ifdef __cforall
    256256        extern "Cforall" {
     257        static inline bool exception_in_flight() {
     258            return __get_stack( &active_thread()->self_cor )->exception_context.current_exception != 0p;
     259        }
     260
    257261                static inline thread$ * volatile & ?`next ( thread$ * this ) {
    258262                        return this->user_link.next;
  • libcfa/src/concurrency/kernel.cfa

    r4c8ce47 rb93bf85  
    569569                returnToKernel();
    570570        __enable_interrupts_checked();
    571 
    572571}
    573572
  • libcfa/src/concurrency/locks.cfa

    r4c8ce47 rb93bf85  
    239239}
    240240
    241 void on_selected( blocking_lock & this, select_node & node ) {}
     241bool on_selected( blocking_lock & this, select_node & node ) { return true; }
    242242
    243243//-----------------------------------------------------------------------------
  • libcfa/src/concurrency/locks.hfa

    r4c8ce47 rb93bf85  
    112112static inline bool   register_select( single_acquisition_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); }
    113113static inline bool   unregister_select( single_acquisition_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); }
    114 static inline void   on_selected( single_acquisition_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); }
     114static inline bool   on_selected( single_acquisition_lock & this, select_node & node ) { return on_selected( (blocking_lock &)this, node ); }
    115115
    116116//----------
     
    129129static inline bool   register_select( owner_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); }
    130130static inline bool   unregister_select( owner_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); }
    131 static inline void   on_selected( owner_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); }
     131static inline bool   on_selected( owner_lock & this, select_node & node ) { return on_selected( (blocking_lock &)this, node ); }
    132132
    133133//-----------------------------------------------------------------------------
     
    619619}
    620620
    621 static inline void on_selected( simple_owner_lock & this, select_node & node ) {}
     621static inline bool on_selected( simple_owner_lock & this, select_node & node ) { return true; }
    622622
    623623
  • libcfa/src/concurrency/select.cfa

    r4c8ce47 rb93bf85  
    4949    return false;
    5050}
    51 void on_selected( select_timeout_node & this, select_node & node ) {}
     51bool on_selected( select_timeout_node & this, select_node & node ) { return true; }
    5252
    5353// Gateway routine to wait on duration
  • libcfa/src/concurrency/select.hfa

    r4c8ce47 rb93bf85  
    9696    //    passed as an arg to this routine
    9797    // If on_selected returns false, the statement is not run, if it returns true it is run.
    98     void on_selected( T &, select_node & );
     98    bool on_selected( T &, select_node & );
    9999};
    100100
     
    208208bool register_select( select_timeout_node & this, select_node & node );
    209209bool unregister_select( select_timeout_node & this, select_node & node );
    210 void on_selected( select_timeout_node & this, select_node & node );
     210bool on_selected( select_timeout_node & this, select_node & node );
    211211
    212212// Gateway routines to waituntil on duration
  • src/Concurrency/Waituntil.cpp

    r4c8ce47 rb93bf85  
    12901290    // Collection of unregister calls on resources to be put in finally clause
    12911291    // for each clause:
    1292     // when_cond_i = (!__CFA_has_clause_run( clause_statuses[i] )) && unregister_select( ... , clausei );
     1292    // if ( !__CFA_has_clause_run( clause_statuses[i] )) && unregister_select( ... , clausei ) ) { ... clausei stmt ... }
    12931293    // OR if when( ... ) defined on resource
    1294     // if ( when_cond_i )
    1295     //   when_cond_i =  (!__CFA_has_clause_run( clause_statuses[i] )) && unregister_select( ... , clausei );
     1294    // if ( when_cond_i && (!__CFA_has_clause_run( clause_statuses[i] )) && unregister_select( ... , clausei ) ) { ... clausei stmt ... }
    12961295    CompoundStmt * unregisters = new CompoundStmt( loc );
    1297 
    12981296
    12991297    Expr * statusExpr; // !__CFA_has_clause_run( clause_statuses[i] )
     
    13481346            new IfStmt( cLoc,
    13491347                statusExpr,
    1350                 genStmtBlock( stmt->clauses.at(i), clauseData.at(i) )
    1351             )
    1352         );
     1348                new CompoundStmt( cLoc,
     1349                    {
     1350                        new IfStmt( cLoc,
     1351                            genSelectTraitCall( stmt->clauses.at(i), clauseData.at(i), "on_selected" ),
     1352                            ast::deepCopy( stmt->clauses.at(i)->stmt )
     1353                        )
     1354                    }
     1355                )
     1356            )
     1357        );
     1358
     1359        // // generates:
     1360        // // if ( statusExpr ) { ... clausei stmt ... }
     1361        // unregisters->push_back(
     1362        //     new IfStmt( cLoc,
     1363        //         statusExpr,
     1364        //         genStmtBlock( stmt->clauses.at(i), clauseData.at(i) )
     1365        //     )
     1366        // );
    13531367    }
    13541368
Note: See TracChangeset for help on using the changeset viewer.