/* Test thread options work as expected */ static void test_options(void) { gpr_thd_options options = gpr_thd_options_default(); GPR_ASSERT(!gpr_thd_options_is_joinable(&options)); GPR_ASSERT(gpr_thd_options_is_detached(&options)); gpr_thd_options_set_joinable(&options); GPR_ASSERT(gpr_thd_options_is_joinable(&options)); GPR_ASSERT(!gpr_thd_options_is_detached(&options)); gpr_thd_options_set_detached(&options); GPR_ASSERT(!gpr_thd_options_is_joinable(&options)); GPR_ASSERT(gpr_thd_options_is_detached(&options)); }
int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg, const gpr_thd_options *options) { int thread_started; pthread_attr_t attr; pthread_t p; /* don't use gpr_malloc as we may cause an infinite recursion with * the profiling code */ struct thd_arg *a = malloc(sizeof(*a)); GPR_ASSERT(a != NULL); a->body = thd_body; a->arg = arg; GPR_ASSERT(pthread_attr_init(&attr) == 0); if (gpr_thd_options_is_detached(options)) { GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0); } else { GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == 0); } thread_started = (pthread_create(&p, &attr, &thread_body, a) == 0); GPR_ASSERT(pthread_attr_destroy(&attr) == 0); if (!thread_started) { free(a); } *t = (gpr_thd_id)p; return thread_started; }
int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg, const gpr_thd_options *options) { int thread_started; pthread_attr_t attr; pthread_t p; struct thd_arg *a = gpr_malloc(sizeof(*a)); a->body = thd_body; a->arg = arg; GPR_ASSERT(pthread_attr_init(&attr) == 0); if (gpr_thd_options_is_detached(options)) { GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0); } else { GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == 0); } thread_started = (pthread_create(&p, &attr, &thread_body, a) == 0); GPR_ASSERT(pthread_attr_destroy(&attr) == 0); if (!thread_started) { gpr_free(a); } *t = (gpr_thd_id)p; return thread_started; }