コード例 #1
0
ファイル: bdberl_tpool.c プロジェクト: chinnurtb/bdberl
static void* bdberl_tpool_main(void* arg)
{
    TPool* tpool = (TPool*)arg;

    LOCK(tpool);

    tpool->active_threads++;

    while(1)
    {
        // Check for shutdown...
        if (tpool->shutdown)
        {
            tpool->active_threads--;
            erl_drv_cond_broadcast(tpool->work_cv);
            UNLOCK(tpool);
            return 0;
        }

        // Get the next job
        TPoolJob* job = next_job(tpool);
        if (job)
        {
            // Unlock to avoid blocking others
            UNLOCK(tpool);

            // Invoke the function
            (*(job->main_fn))(job->arg);

            // Relock
            LOCK(tpool);

            // Mark the job as not running (important for cancellation to know it's done)
            job->running = 0;

            // If the job was cancelled, signal the cancellation cv so that anyone waiting on the
            // job knows it's complete
            if (job->canceled)
            {
                erl_drv_cond_broadcast(tpool->cancel_cv);
            }
        
            // Cleanup the job (remove from active list, free, etc.)
            cleanup_job(tpool, job);
        }
        else
        {
            // Wait for a job to come available then jump back to top of loop
            erl_drv_cond_wait(tpool->work_cv, tpool->lock);
        }
    }

    return 0;
}
コード例 #2
0
ファイル: bdberl_tpool.c プロジェクト: chinnurtb/bdberl
void bdberl_tpool_run(TPool* tpool, TPoolJobFunc main_fn, void* arg, TPoolJobFunc cancel_fn, 
                      TPoolJob** job_ptr)
{
    // Allocate and fill a new job structure
    TPoolJob* job = *job_ptr = driver_alloc(sizeof(TPoolJob));
    memset(job, '\0', sizeof(TPoolJob));
    job->main_fn = main_fn;
    job->arg = arg;
    job->cancel_fn = cancel_fn;

    // Sync up with the tpool and add the job to the pending queue
    LOCK(tpool);
    
    if (tpool->pending_jobs)
    {
        // Make sure the current last job points to this one next
        tpool->last_pending_job->next = job;
    }
    else
    {
        // No pending jobs; this is the first
        tpool->pending_jobs = job;
    }

    tpool->last_pending_job = job;
    tpool->pending_job_count++;

    // Generate a notification that there is work todo. 
    // TODO: I think this may not be necessary, in the case where there are already other
    // pending jobs. Not sure ATM, however, so will be on safe side
    erl_drv_cond_broadcast(tpool->work_cv);
    UNLOCK(tpool);
}
コード例 #3
0
ファイル: bdberl_tpool.c プロジェクト: chinnurtb/bdberl
void bdberl_tpool_stop(TPool* tpool)
{
    LOCK(tpool);

    // Set the shutdown flag and broadcast a notification
    tpool->shutdown = 1;
    erl_drv_cond_broadcast(tpool->work_cv);

    // Clean out the queue of pending jobs -- invoke their cleanup function

    // Wait for until active_threads hits zero
    while (tpool->active_threads > 0)
    {
        erl_drv_cond_wait(tpool->work_cv, tpool->lock);
    }
    
    // Join up with all the workers
    int i = 0;
    for (i = 0; i < tpool->thread_count; i++)
    {
        erl_drv_thread_join(tpool->threads[i], 0);
    }

    // Cleanup 
    erl_drv_cond_destroy(tpool->work_cv);
    erl_drv_cond_destroy(tpool->cancel_cv);
    driver_free(tpool->threads);
    UNLOCK(tpool);
    erl_drv_mutex_destroy(tpool->lock);
    driver_free(tpool);
}
コード例 #4
0
ファイル: erl_nif.c プロジェクト: a5an0/otp
void enif_cond_broadcast(ErlNifCond *cnd) { erl_drv_cond_broadcast(cnd); }
コード例 #5
0
ファイル: erl_obsolete.c プロジェクト: AugustoFernandes/otp
int
erts_cond_broadcast(erl_cond_t cnd)
{
    erl_drv_cond_broadcast((ErlDrvCond *) cnd);
    return 0;
}