Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/kernel/fwd.hfa

    rfc2c57a9 r563a36b  
    254254                        // intented to be use by wait, wait_any, waitfor, etc. rather than used directly
    255255                        bool setup( future_t & this, oneshot & wait_ctx ) {
    256                                 /* paranoid */ verify( wait_ctx.ptr == 0p || wait_ctx.ptr == 1p );
     256                                /* paranoid */ verify( wait_ctx.ptr == 0p );
    257257                                // The future needs to set the wait context
    258258                                for() {
     
    274274                        // intented to be use by wait, wait_any, waitfor, etc. rather than used directly
    275275                        bool retract( future_t & this, oneshot & wait_ctx ) {
    276                                 struct oneshot * expected = this.ptr;
    277 
    278                                 // attempt to remove the context so it doesn't get consumed.
    279                                 if(__atomic_compare_exchange_n( &this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
     276                                for() {
     277                                        struct oneshot * expected = this.ptr;
     278
     279                                        // expected == 0p: future was never actually setup, just return
     280                                        if( expected == 0p ) return false;
     281
     282                                        // expected == 1p: the future is ready and the context was fully consumed
     283                                        // the server won't use the pointer again
     284                                        // It is safe to delete (which could happen after the return)
     285                                        if( expected == 1p ) return true;
     286
     287                                        // expected == 2p: the future is ready but the context hasn't fully been consumed
     288                                        // spin until it is safe to move on
     289                                        if( expected == 2p ) {
     290                                                while( this.ptr != 1p ) Pause();
     291                                                /* paranoid */ verify( this.ptr == 1p );
     292                                                return true;
     293                                        }
     294
     295                                        // expected != wait_ctx: the future was setup with a different context ?!?!
     296                                        // something went wrong here, abort
     297                                        if( expected != &wait_ctx ) abort("Future in unexpected state");
     298
    280299                                        // we still have the original context, then no one else saw it
    281                                         return false;
    282                                 }
    283 
    284                                 // expected == 0p: future was never actually setup, just return
    285                                 if( expected == 0p ) return false;
    286 
    287                                 // expected == 1p: the future is ready and the context was fully consumed
    288                                 // the server won't use the pointer again
    289                                 // It is safe to delete (which could happen after the return)
    290                                 if( expected == 1p ) return true;
    291 
    292                                 // expected == 2p: the future is ready but the context hasn't fully been consumed
    293                                 // spin until it is safe to move on
    294                                 if( expected == 2p ) {
    295                                         while( this.ptr != 1p ) Pause();
    296                                         /* paranoid */ verify( this.ptr == 1p );
    297                                         return true;
    298                                 }
    299 
    300                                 // anything else: the future was setup with a different context ?!?!
    301                                 // something went wrong here, abort
    302                                 abort("Future in unexpected state");
     300                                        // attempt to remove the context so it doesn't get consumed.
     301                                        if(__atomic_compare_exchange_n( &this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
     302                                                return false;
     303                                        }
     304                                }
    303305                        }
    304306
Note: See TracChangeset for help on using the changeset viewer.