Branch: Tag:

2016-10-26

2016-10-26 12:45:26 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Concurrent.Promise: Changed API somewhat.

success() and failure() now throw errors if the Future isn't
in the STATE_PENDING state.

Add try_success() that is a noop if the Future isn't pending.

Renamed maybe_failure() to try_failure() for symmetry with try_success().

Clean up FirstCompleted by using try_success() and try_failure().

283:    Promise p = Promise();    on_failure(p->failure);    on_success(p->success); -  call_out(p->maybe_failure, seconds, ({ "Timeout.\n", backtrace() })); +  call_out(p->try_failure, seconds, ({ "Timeout.\n", backtrace() }));    return p->future();    }   }
328:    //! @param value    //! Result of the @[Future].    //! -  //! Mark the @[Future] as fulfilled if it hasn't already been failed, -  //! and schedule the @[on_success()] callbacks to be called as soon -  //! as possible. +  //! @throws +  //! Throws an error if the @[Future] already has been fulfilled +  //! or failed.    //! -  +  //! Mark the @[Future] as fulfilled, and schedule the @[on_success()] +  //! callbacks to be called as soon as possible. +  //!    //! @seealso -  //! @[maybe_failure()], @[failure()], @[on_success()] +  //! @[try_success()], @[try_failure()], @[failure()], @[on_success()]    void success(mixed value)    { -  +  if (state) error("Promise has already been finalized.\n");    object key = mux->lock(); -  +  if (state) error("Promise has already been finalized.\n");    unlocked_success(value);    key = 0;    }    -  +  //! Fulfill the @[Future] if it hasn't been fulfilled or failed already. +  //! +  //! @param value +  //! Result of the @[Future]. +  //! +  //! Mark the @[Future] as fulfilled if it hasn't already been fulfilled +  //! or failed, and in that case schedule the @[on_success()] callbacks +  //! to be called as soon as possible. +  //! +  //! @seealso +  //! @[success()], @[try_failure()], @[failure()], @[on_success()] +  void try_success(mixed value) +  { +  if (state) return; +  object key = mux->lock(); +  if (state) return; +  unlocked_success(value); +  key = 0; +  } +     protected void unlocked_failure(mixed value)    {    state = STATE_REJECTED;
360:    //! @param value    //! Failure result of the @[Future].    //! +  //! @throws +  //! Throws an error if the @[Future] already has been fulfilled +  //! or failed. +  //!    //! Mark the @[Future] as failed, and schedule the @[on_failure()]    //! callbacks to be called as soon as possible.    //!    //! @seealso -  //! @[maybe_failure()], @[success()], @[on_failure()] +  //! @[try_failure()], @[success()], @[on_failure()]    void failure(mixed value)    { -  +  if (state) error("Promise has already been finalized.\n");    object key = mux->lock(); -  +  if (state) error("Promise has already been finalized.\n");    unlocked_failure(value);    key = 0;    }
378:    //! Failure result of the @[Future].    //!    //! Mark the @[Future] as failed if it hasn't already been fulfilled, -  //! and schedule the @[on_failure()] callbacks to be called as soon -  //! as possible. +  //! and in that case schedule the @[on_failure()] callbacks to be +  //! called as soon as possible.    //!    //! @seealso    //! @[failure()], @[success()], @[on_failure()] -  void maybe_failure(mixed value) +  void try_failure(mixed value)    { -  +  if (state) return;    object key = mux->lock();    if (state) return;    unlocked_failure(value);
408:    state = STATE_FULFILLED;    return;    } -  futures->on_failure(got_failure); -  futures->on_success(got_success); +  futures->on_failure(try_failure); +  futures->on_success(try_success);    } -  -  protected void got_failure(mixed err) -  { -  if (state) return; -  failure(err); +    }    -  protected void got_success(mixed val) -  { -  if (state) return; -  success(val); -  } - } -  +    //! Return a @[Future] that represents the first   //! of the @[futures] that completes.   Future first_completed(array(Future) futures)