pike.git / lib / modules / Thread.pmod

version» Context lines:

pike.git/lib/modules/Thread.pmod:400: Inside #if constant(__builtin.thread_id)
  class Farm   {    protected Mutex mutex = Mutex();    protected Condition ft_cond = Condition();    protected Queue job_queue = Queue();    protected object dispatcher_thread;    protected function(object, string:void) thread_name_cb;    protected string thread_name_prefix;       //! An asynchronous result. +  //! +  //! @fixme +  //! This class ought to be made @[Concurrent.Future]-compatible.    class Result    {    int ready;    mixed value;    function done_cb;       //! @returns    //! @int    //! @value 1    //! Returns @expr{1@} when the result is available.
pike.git/lib/modules/Thread.pmod:493: Inside #if constant(__builtin.thread_id)
   switch( f )    {    case 't':    return "Thread.Farm().Result";    case 'O':    return sprintf( "%t(%d %O)", this, ready, value );    }    }    }    +  protected void report_errors(mixed err, int is_err) +  { +  if (!is_err) return; +  master()->handle_error(err); +  } +  +  //! A wrapper for an asynchronous result. +  //! +  //! @note +  //! This wrapper is used to detect when the +  //! user discards the values returned from +  //! @[run()] or @[run_multiple()], so that +  //! any errors thrown aren't lost. +  protected class ResultWrapper(Result ro) +  { +  protected int(0..1) value_fetched; +  int `ready() { return ro->ready; } +  mixed `value() { +  value_fetched = 1; +  return ro->value; +  } +  function `done_cb() { return ro->done_cb; } +  void `done_cb=(function cb) { +  if (cb) value_fetched = 1; +  ro->done_cb = cb; +  } +  +  //! @returns +  //! @int +  //! @value 1 +  //! Returns @expr{1@} when the result is available. +  //! @value 0 +  //! Returns @expr{0@} (zero) when the result hasn't +  //! arrived yet. +  //! @value -1 +  //! Returns negative on failure. +  //! @endint +  function(:int) `status() { return ro->status; } +  +  //! @returns +  //! Returns the result if available, a backtrace on failure, +  //! and @expr{0@} (zero) otherwise. +  function(:mixed) `result() { return ro->result; } +  +  //! Wait for completion. +  mixed `()() +  { +  return ro(); +  } +  +  //! Register a callback to be called when +  //! the result is available. +  //! +  //! @param to +  //! Callback to be called. The first +  //! argument to the callback will be +  //! the result or the failure backtrace, +  //! and the second @expr{0@} (zero) on +  //! success, and @expr{1@} on failure. +  void set_done_cb(function cb) { +  if (cb) value_fetched = 1; +  ro->set_done_cb(cb); +  } +  +  //! Register a failure. +  //! +  //! @param what +  //! The corresponding backtrace. +  function(mixed:void) `provide_error() { return ro->provide_error; } +  +  //! Register a completed result. +  //! +  //! @param what +  //! The result to register. +  function(mixed:void) `provide() { return ro->provide; } +  +  protected void _destruct() +  { +  if (ro && !value_fetched && !ro->done_cb) { +  // Make sure that any errors aren't lost. +  ro->done_cb = report_errors; +  if (ro->ready < 0) { +  report_errors(ro->value, 1); +  } +  } +  } +  +  protected string _sprintf( int f ) +  { +  switch( f ) +  { +  case 't': +  return "Thread.Farm().ResultWrapper"; +  case 'O': +  return sprintf("%t(%O)", this, ro); +  } +  } +  } +     //! A worker thread.    protected class Handler    {    Mutex job_mutex = Mutex();    Condition cond = Condition();    array(object|array(function|array)) job;    object thread;       float total_time;    int handled, max_time;
pike.git/lib/modules/Thread.pmod:683: Inside #if constant(__builtin.thread_id)
   //! If any of the functions in @[fun_args] throws    //! and error, all of the accumulated results    //! (if any) will be dropped from the result, and    //! the first backtrace be provided.    //!    //! @seealso    //! @[run_multiple_async()]    Result run_multiple( array(array(function|array)) fun_args )    {    Result r = Result(); // private result.. +  ResultWrapper rw = ResultWrapper(r);    r->value = allocate( sizeof( fun_args ) );    mapping nl = ([ "num_left":sizeof( fun_args ) ]);    for( int i=0; i<sizeof( fun_args ); i++ )    {    Result r2 = Result();    r2->set_done_cb( ValueAdjuster( r, r2, i, nl )->go );    job_queue->write( ({ r2, fun_args[i] }) );    } -  return r; +  return rw;    }          //! Register multiple jobs where the return values    //! are to be ignored.    //!    //! @param fun_args    //! An array of arrays where the first element    //! is a function to call, and the second is    //! a corresponding array of arguments.
pike.git/lib/modules/Thread.pmod:738: Inside #if constant(__builtin.thread_id)
   //! @note    //! In Pike 7.8 and earlier this function    //! was broken and returned a @[Result]    //! object that wasn't connected to the job.    //!    //! @seealso    //! @[run_async()]    Result run( function f, mixed ... args )    {    Result ro = Result(); +  ResultWrapper rw = ResultWrapper(ro);    job_queue->write( ({ ro, ({f, args }) }) ); -  return ro; +  return rw;    }       //! Register a job for the thread farm    //! where the return value from @[f] is    //! ignored.    //!    //! @param f    //! Function to call with @@@[args] to    //! perform the job.    //!