Changes in / [9c6443e:25404c7]


Ignore:
File:
1 edited

Legend:

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

    r9c6443e r25404c7  
    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 );
     256                                /* paranoid */ verify( wait_ctx.ptr == 0p || wait_ctx.ptr == 1p );
    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                                 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 
     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)) {
    299280                                        // we still have the original context, then no one else saw it
    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                                 }
     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");
    305303                        }
    306304
Note: See TracChangeset for help on using the changeset viewer.