pike.git / lib / modules / Concurrent.pmod

version» Context lines:

pike.git/lib/modules/Concurrent.pmod:65:    State s = state;    mixed res = result;    if (!s) {    Thread.MutexKey key = mux->lock();    while (!state) {    cond->wait(key);    }       s = state;    res = result; -  key = 0; +     }       if (s == STATE_REJECTED) {    throw(res);    }    return res;    }       //! Register a callback that is to be called on fulfillment.    //!
pike.git/lib/modules/Concurrent.pmod:91:    //! Any extra context needed for @[cb]. They will be provided    //! as arguments two and onwards when @[cb] is called.    //!    //! @note    //! @[cb] will always be called from the main backend.    //!    //! @seealso    //! @[on_failure()]    this_program on_success(function(mixed, mixed ... : void) cb, mixed ... extra)    { -  Thread.MutexKey key = mux->lock(); -  -  if (state == STATE_FULFILLED) { -  key = 0; +  switch (state) { +  case STATE_FULFILLED:    callout(cb, 0, result, @extra); -  } else { +  break; +  case STATE_PENDING: +  // Rely on interpreter lock to add to success_cbs before state changes +  // again    success_cbs += ({ ({ cb, @extra }) }); -  key = 0; +     } -  +     return this_program::this;    }       //! Register a callback that is to be called on failure.    //!    //! @param cb    //! Function to be called. The first argument will be the    //! failure result of the @[Future].    //!    //! @param extra    //! Any extra context needed for @[cb]. They will be provided    //! as arguments two and onwards when @[cb] is called.    //!    //! @note    //! @[cb] will always be called from the main backend.    //!    //! @seealso    //! @[on_success()]    this_program on_failure(function(mixed, mixed ... : void) cb, mixed ... extra)    { -  Thread.MutexKey key = mux->lock(); -  -  if (state == STATE_REJECTED) { -  key = 0; +  switch (state) { +  case STATE_REJECTED:    callout(cb, 0, result, @extra); -  } else { +  break; +  case STATE_PENDING: +  // Rely on interpreter lock to add to failure_cbs before state changes +  // again    failure_cbs += ({ ({ cb, @extra }) }); -  key = 0; +     } -  +     return this_program::this;    }       //! Apply @[fun] with @[val] followed by the contents of @[ctx],    //! and update @[p] with the result.    protected void apply(mixed val, Promise p,    function(mixed, mixed ... : mixed) fun,    array(mixed) ctx)    {    mixed err = catch {
pike.git/lib/modules/Concurrent.pmod:472:       private void create(Promise p)    {    if (p->_materialised || p->_materialised++)    error("Cannot materialise a Promise more than once.\n");    promise = p;    }       final void materialise()    { -  Thread.MutexKey key = mux->lock(); +     if (promise->_astate)    {    promise->_astate = 0; -  key = 0; +     if (results)    {    promises = sizeof(results);    array(Future) futures = results;    if (fold_fun)    results = 0;    foreach(futures; int idx; Future f)    {    f->on_failure(cb_failure, idx);    f->on_success(cb_success, idx);    }    }    } -  key = 0; +     }       private void fold_one(mixed val)    {    mixed err = catch (accumulator = fold_fun(val, accumulator, @extra));    if (err && promise)    promise->failure(err);    }       private void fold(function(mixed:void) failsucc)
pike.git/lib/modules/Concurrent.pmod:535:    if (results)    results[idx] = value;    else    fold_one(value);    if (success)    {    fold(failed >= min_failures ? p->success : p->failure);    break;    }    } -  else -  key = 0; +     return;    } while (0);    promise = 0; // Free backreference    }    }       private void cb_success(mixed value, int idx)    {    Promise p; // Cache it, to cover a failure race    if (p = promise)
pike.git/lib/modules/Concurrent.pmod:572:    if (results)    results[idx] = value;    else    fold_one(value);    if (success)    {    fold(p->success);    break;    }    } -  else -  key = 0; +     return;    } while (0);    promise = 0; // Free backreference    }    }   }      //! Promise to provide a @[Future] value.   //!   //! Objects of this class are typically kept internal to the
pike.git/lib/modules/Concurrent.pmod:613:    function(function(mixed:void),    function(mixed:void), mixed ...:void) executor, mixed ... extra)    {    if (executor)    executor(success, failure, @extra);    }       Future on_success(function(mixed, mixed ... : void) cb, mixed ... extra)    {    if (_astate) -  catch(_astate->materialise()); // catches race for _astate == 0 +  _astate->materialise();    return ::on_success(cb, @extra);    }       Future on_failure(function(mixed, mixed ... : void) cb, mixed ... extra)    {    if (_astate) -  catch(_astate->materialise()); // catches race for _astate == 0 +  _astate->materialise();    return ::on_failure(cb, @extra);    }       mixed get()    {    if (_astate) -  catch(_astate->materialise()); // catches race for _astate == 0 +  _astate->materialise();    return ::get();    }       //! The future value that we promise.    Future future()    {    return Future::this;    }       protected this_program finalise(State newstate, mixed value, int try,