static void *f_threadpool_routine(void *arg) { t_threadpool_data *data; t_threadpool *v_this; t_threadpool_task *task; bool run; run = true; v_this = (t_threadpool *)arg; while (run == true) { if (D_LOCK(lock)(&v_this->v_data, (void **)&data) == true) { run = data->v_run; task = D_QUEUE(pop)(&data->v_tasks); D_LOCK(release)(&v_this->v_data, (void **)&data); if (run == true && task != NULL) { task->f_funct(task->v_data); uf_free_s((void **)&task); } } usleep(5000); } return (NULL); }
int main(int argc, char const** argv) { /* * Create all threads you want */ t_share private_share; t_lock lock; t_share *acces_share; dprintf(1, "Init lock\n"); if (D_LOCK(init)(&lock, &private_share) == false) return (1); /* * safe access */ dprintf(1, "Lock variable\n"); if (D_LOCK(lock)(&lock, (void **)&acces_share) == true) { acces_share->var1 = 1; /* * treat variable */ D_LOCK(release)(&lock, (void **)&acces_share); /* * if here you access at the variable, you will crash because * acces_share == NULL */ dprintf(1, "Release variable\n"); } D_LOCK(destroy)(&lock); dprintf(1, "Destroy lock\n"); (void)argc; (void)argv; return (0); }
bool f_threadpool_init(t_threadpool *v_this, size_t nb_thread) { t_threadpool_data *data; v_this->pv_data.v_run = false; if ((v_this->v_id = uf_malloc_s(nb_thread, sizeof(*v_this->v_id))) == NULL) return (M_ERROR(false, "Bad alloc")); D_QUEUE(init)(&v_this->pv_data.v_tasks, free); if (D_LOCK(init)(&v_this->v_data, &v_this->pv_data, e_lock_default) == false) { uf_free_s((void **)&v_this->v_id); return (M_ERROR(false, "Couldn't initialize lock")); } if (D_LOCK(lock)(&v_this->v_data, (void **)&data) == true) return (D_THREADPOOL(create)(v_this, data, nb_thread)); D_LOCK(destroy)(&v_this->v_data); uf_free_s((void **)&v_this->v_id); return (M_ERROR(false, "An error has occured")); }
void f_threadpool_destroy(t_threadpool *v_this) { size_t i; t_threadpool_data *data; i = 0; if (D_LOCK(lock)(&v_this->v_data, (void **)&data) == true) { data->v_run = false; D_LOCK(release)(&v_this->v_data, (void **)&data); } while (i < v_this->v_nb_thread) { if (pthread_join(v_this->v_id[i], NULL) != 0) M_INFOS("pthread_join error"); i = i + 1; } D_LOCK(destroy)(&v_this->v_data); D_QUEUE(destroy)(&v_this->pv_data.v_tasks); uf_free_s((void **)&v_this->v_id); }
bool f_threadpool_add_task(t_threadpool *v_this, t_threadpool_task *task) { t_threadpool_task *add; t_threadpool_data *data; if ((add = uf_malloc_s(1, sizeof(*add))) == NULL) return (M_ERROR(false, "Bad alloc")); uf_memcpy(add, task, sizeof(*add)); if (D_LOCK(lock)(&v_this->v_data, (void **)&data) == true) { if (D_QUEUE(push)(&data->v_tasks, add) == false) { uf_free_s((void **)&add); D_LOCK(release)(&v_this->v_data, (void **)&data); return (M_ERROR(false, "Couldn't add tasks")); } D_LOCK(release)(&v_this->v_data, (void **)&data); return (true); } uf_free_s((void **)&add); return (false); }
static bool f_threadpool_create(t_threadpool *v_this, t_threadpool_data *data, size_t nb_thread) { size_t i; i = 0; while (i < nb_thread) { if (pthread_create(&v_this->v_id[i], NULL, D_THREADPOOL(routine), v_this) != 0) break ; i = i + 1; } if (i == nb_thread) data->v_run = true; v_this->v_nb_thread = i; D_LOCK(release)(&v_this->v_data, (void **)&data); if (i != nb_thread) { D_THREADPOOL(destroy)(v_this); return (M_ERROR(false, "Couldn't create thread")); } return (true); }