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; }
job::~job() { cleanup_job(); }