pike.git / lib / modules / Thread.pmod

version» Context lines:

pike.git/lib/modules/Thread.pmod:422: Inside #if constant(thread_create)
   return items;    }       protected string _sprintf( int f )    {    return f=='O' && sprintf( "%O(%d)", this_program, size() );    }   }       -  + //! A thread farm.   optional class Farm   {    protected Mutex mutex = Mutex();    protected Condition ft_cond = Condition();    protected Queue job_queue = Queue();    -  +  //! An asynchronous result.    class Result    {    int ready;    mixed value;    function done_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    int status()    {    return ready;    }    -  +  //! @returns +  //! Returns the result if available, a backtrace on failure, +  //! and @expr{0@} (zero) otherwise.    mixed result()    {    return value;    }    -  +  //! Wait for completion.    mixed `()()    {    object key = mutex->lock();    while(!ready) ft_cond->wait(key);    key = 0;    if( ready < 0 ) throw( value );    return value;    }    -  +  //! 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 to )    {    if( ready )    to( value, ready<0 );    else    done_cb = to;    }    -  +  //! Register a failure. +  //! +  //! @param what +  //! The corresponding backtrace.    void provide_error( mixed what )    {    value = what;    ready = -1;    if( done_cb )    done_cb( what, 1 );    }    -  +  //! Register a completed result. +  //! +  //! @param what +  //! The result to register.    void provide( mixed what )    {    ready = 1;    value = what;    if( done_cb )    done_cb( what, 0 );    }          protected string _sprintf( int f )
pike.git/lib/modules/Thread.pmod:491: Inside #if constant(thread_create)
   switch( f )    {    case 't':    return "Thread.Farm().Result";    case 'O':    return sprintf( "%t(%d %O)", this, ready, value );    }    }    }    +  //! 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:549: Inside #if constant(thread_create)
      void run( array(function|array) what, object|void resobj )    {    while(!ready) sleep(0.1);    object key = job_mutex->lock();    job = ({ resobj, what });    cond->signal();    key = 0;    }    +  //! Get some statistics about the worker thread.    string debug_status()    {    return ("Thread:\n"    " Handled works: "+handled+"\n"+    (handled?    " Average time: "+((int)(total_time / handled))+"ms\n"    " Max time: "+sprintf("%2.2fms\n", max_time/1000.0):"")+    " Status: "+(job?"Working":"Idle" )+"\n"+    (job?    (" "+
pike.git/lib/modules/Thread.pmod:617: Inside #if constant(thread_create)
   protected void dispatcher()    {    while( array q = [array]job_queue->read() )    aquire_thread()->run( q[1], q[0] );    }       protected class ValueAdjuster( object r, object r2, int i, mapping v )    {    void go(mixed vn, int err)    { +  if (!r->status()) {    ([array]r->value)[ i ] = vn;    if( err )    r->provide_error( err );    if( !--v->num_left )    r->provide( r->value ); -  +  }    destruct();    }    }    -  object run_multiple( array fun_args ) +  +  //! Register multiple jobs. +  //! +  //! @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. +  //! +  //! @returns +  //! Returns a @[Result] object with an array +  //! with one element for the result for each +  //! of the functions in @[fun_args]. +  //! +  //! @note +  //! Do not modify the elements of @[fun_args] +  //! before the result is available. +  //! +  //! @note +  //! If any of the functions in @[fun_args] throws +  //! and error, all of the accululated 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..    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(); +  Result r2 = Result();    r2->set_done_cb( ValueAdjuster( r, r2, i, nl )->go );    job_queue->write( ({ r2, fun_args[i] }) );    }    return r;    }       -  +  //! 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. +  //! +  //! @note +  //! Do not modify the elements of @[fun_args] +  //! before the result is available. +  //! +  //! @seealso +  //! @[run_multiple()]    void run_multiple_async( array fun_args )    {    for( int i=0; i<sizeof( fun_args ); i++ )    job_queue->write( ({ 0, fun_args[i] }) );    }       -  object run( function f, mixed ... args ) +  //! Register a job for the thread farm. +  //! +  //! @param f +  //! Function to call with @@@[args] to +  //! perform the job. +  //! +  //! @param args +  //! The parameters for @[f]. +  //! +  //! @returns +  //! Returns a @[Result] object for the job. +  //! +  //! @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 )    { -  object ro = Result(); -  job_queue->write( ({ 0, ({f, args }) }) ); +  Result ro = Result(); +  job_queue->write( ({ ro, ({f, args }) }) );    return ro;    }    -  +  //! 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. +  //! +  //! @param args +  //! The parameters for @[f]. +  //! +  //! @seealso +  //! @[run()]    void run_async( function f, mixed ... args )    {    job_queue->write( ({ 0, ({f, args }) }) );    }    -  int set_max_num_threads( int to ) +  //! Set the maximum number of worker threads +  //! that the thread farm may have. +  //! +  //! @param to +  //! The new maximum number. +  //! +  //! If there are more worker threads than @[to], +  //! the function will wait until enough threads +  //! have finished, so that the total is @[to] or less. +  //! +  //! The default maximum number of worker threads is @expr{20@}. +  int set_max_num_threads( int(1..) to )    {    int omnt = max_num_threads;    if( to <= 0 )    error("Illegal argument 1 to set_max_num_threads,"    "num_threads must be > 0\n");       max_num_threads = to;    while( sizeof( threads ) > max_num_threads )    {    object key = mutex->lock();    while( sizeof( free_threads ) )    free_threads[0]->cond->signal();    if( sizeof( threads ) > max_num_threads)    ft_cond->wait(key);    }    ft_cond->broadcast( );    return omnt;    }    -  +  //! Get some statistics for the thread farm.    string debug_status()    {    string res = sprintf("Thread farm\n"    " Max threads = %d\n"    " Current threads = %d\n"    " Working threads = %d\n"    " Jobs in queue = %d\n\n",    max_num_threads, sizeof(threads),    (sizeof(threads)-sizeof(free_threads)),    job_queue->size() );