Skip to content

Commit

Permalink
Let rd_thread_create() assign the thread variable to avoid race condi…
Browse files Browse the repository at this point in the history
…tions.
  • Loading branch information
edenhill committed May 6, 2013
1 parent 147d33f commit 43b0cc4
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 26 deletions.
10 changes: 5 additions & 5 deletions rdiothread.c
Expand Up @@ -134,9 +134,10 @@ static rd_thread_t *rd_io_worker_get (void) {
}

/* Create new worker */
rdt = rd_thread_create(rd_tsprintf("rd:io:%i",
rd_thread_create(&rdt, rd_tsprintf("rd:io:%i",
rd_io_worker_cnt++),
NULL, rd_io_worker_main, NULL);
NULL, rd_io_worker_main, NULL);
/* FIXME: error handling */
}

return rdt;
Expand Down Expand Up @@ -220,9 +221,8 @@ static int rd_io_thread_start (void) {
return -1;
}

rd_io_thread = rd_thread_create("rd:io", NULL, rd_io_thread_main, NULL);

if (!rd_io_thread) {
if (rd_thread_create(&rd_io_thread, "rd:io", NULL,
rd_io_thread_main, NULL) == -1) {
/* FIXME: log */
rdbg("Failed to create rd:io thread: %s", strerror(errno));
close(rd_io_thread_fd);
Expand Down
38 changes: 22 additions & 16 deletions rdthread.c
Expand Up @@ -127,31 +127,37 @@ rd_thread_t *rd_thread_create0 (const char *name, pthread_t *pthread) {
}


rd_thread_t *rd_thread_create (const char *name,
const pthread_attr_t *attr,
void *(*start_routine)(void*),
void *arg) {
rd_thread_t *rdt;
int rd_thread_create (rd_thread_t **rdt,
const char *name,
const pthread_attr_t *attr,
void *(*start_routine)(void*),
void *arg) {
rd_thread_t *rdt0;

rdt = rd_thread_create0(name, NULL);
rdt0 = rd_thread_create0(name, NULL);

rdt->rdt_start = start_routine;
rdt->rdt_start_arg = arg;
rdt0->rdt_start = start_routine;
rdt0->rdt_start_arg = arg;

if (rdt)
*rdt = rdt0;

/* FIXME: We should block all signals until pthread_create returns. */
if (pthread_create(&rdt->rdt_thread, attr,
rd_thread_start_routine, rdt)) {
if (pthread_create(&rdt0->rdt_thread, attr,
rd_thread_start_routine, rdt0)) {
int errno_save = errno;
rd_thread_destroy(rdt);
rd_thread_destroy(rdt0);
if (rdt)
*rdt = NULL;
errno = errno_save;
return NULL;
return -1;
}

#ifdef PR_SET_NAME
prctl(PR_SET_NAME, (char *)rdt->rdt_name, 0, 0, 0);
prctl(PR_SET_NAME, (char *)rdt0->rdt_name, 0, 0, 0);
#endif

return rdt;
return 0;
}


Expand All @@ -170,7 +176,7 @@ int rd_threads_create (const char *nameprefix, int threadcount,

for (i = 0 ; i < threadcount ; i++) {
sprintf(name, "%s%i", nameprefix, i);
if (!rd_thread_create(name, attr, start_routine, arg))
if (!rd_thread_create(NULL, name, attr, start_routine, arg))
failed++;
}

Expand Down
11 changes: 7 additions & 4 deletions rdthread.h
Expand Up @@ -103,16 +103,19 @@ rd_thread_t *rd_thread_create0 (const char *name, pthread_t *pthread);

/**
* Creates and starts a new thread and returns its rd_thread_t handle.
* The new thread handle is assigned to '*rdt' (if 'rdt' is non-null).
*
* Same semantics as pthread_create() with the following exceptions:
* - User-defined signals are by default blocked by the new thread:
* SIGUSR1, SIGUSR2.
* Use rd_thread_sigmask() to unblock.
*/
rd_thread_t *rd_thread_create (const char *name,
const pthread_attr_t *attr,
void *(*start_routine)(void*),
void *arg);
int rd_thread_create (rd_thread_t **rdt, const char *name,
const pthread_attr_t *attr,
void *(*start_routine)(void*),
void *arg);



/**
* Wrapper around rd_thread_create() for creating multiple ('threadcount')
Expand Down
2 changes: 1 addition & 1 deletion rdtimer.c
Expand Up @@ -244,5 +244,5 @@ void rd_timers_init (void) {
#endif
rd_cond_init(&rd_timers_cond, &attr);

rd_thread_create("rd:timers", NULL, rd_timers_run, NULL);
rd_thread_create(NULL, "rd:timers", NULL, rd_timers_run, NULL);
}

0 comments on commit 43b0cc4

Please sign in to comment.