- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/channel.hfa
r6f774be r70a4ed5 341 341 } 342 342 343 // special case of __handle_waituntil_OR, that does some work to avoid starvation/deadlock case344 static inline bool __handle_pending( dlist( select_node ) & queue, select_node & mine ) {345 while ( !queue`isEmpty ) {346 // if node not a special OR case or if we win the special OR case race break347 if ( !queue`first.clause_status || queue`first.park_counter || __pending_set_other( queue`first, mine, ((unsigned long int)(&(queue`first))) ) )348 return true;349 350 // our node lost the race when toggling in __pending_set_other351 if ( *mine.clause_status != __SELECT_PENDING )352 return false;353 354 // otherwise we lost the special OR race so discard node355 try_pop_front( queue );356 }357 return false;358 }359 360 343 // type used by select statement to capture a chan read as the selected operation 361 344 struct chan_read { … … 391 374 return false; 392 375 } 393 394 if ( __handle_ pending( prods, node) ) {376 377 if ( __handle_waituntil_OR( prods ) ) { 395 378 __prods_handoff( chan, ret ); 396 379 __make_select_node_sat( node ); // need to to mark SAT now that we know operation is done or else threads could get stuck in __mark_select_node … … 398 381 return true; 399 382 } 400 if ( *node.clause_status == __SELECT_PENDING ) 401 __make_select_node_unsat( node ); 383 __make_select_node_unsat( node ); 402 384 } 403 385 // check if we can complete operation. If so race to establish winner in special OR case … … 441 423 } 442 424 static inline bool unregister_select( chan_read(T) & this, select_node & node ) { return unregister_chan( this.chan, node ); } 443 static inline boolon_selected( chan_read(T) & this, select_node & node ) with(this) {425 static inline void on_selected( chan_read(T) & this, select_node & node ) with(this) { 444 426 if ( node.extra == 0p ) // check if woken up due to closed channel 445 427 __closed_remove( chan, ret ); 446 428 // This is only reachable if not closed or closed exception was handled 447 return true;448 429 } 449 430 … … 482 463 return false; 483 464 } 484 485 if ( __handle_ pending( cons, node) ) {465 466 if ( __handle_waituntil_OR( cons ) ) { 486 467 __cons_handoff( chan, elem ); 487 468 __make_select_node_sat( node ); // need to to mark SAT now that we know operation is done or else threads could get stuck in __mark_select_node … … 489 470 return true; 490 471 } 491 if ( *node.clause_status == __SELECT_PENDING ) 492 __make_select_node_unsat( node ); 472 __make_select_node_unsat( node ); 493 473 } 494 474 // check if we can complete operation. If so race to establish winner in special OR case … … 534 514 static inline bool unregister_select( chan_write(T) & this, select_node & node ) { return unregister_chan( this.chan, node ); } 535 515 536 static inline boolon_selected( chan_write(T) & this, select_node & node ) with(this) {516 static inline void on_selected( chan_write(T) & this, select_node & node ) with(this) { 537 517 if ( node.extra == 0p ) // check if woken up due to closed channel 538 518 __closed_insert( chan, elem ); 539 519 540 520 // This is only reachable if not closed or closed exception was handled 541 return true;542 521 } 543 522
Note: See TracChangeset
for help on using the changeset viewer.