Skip to content

Commit

Permalink
Set the thread name before detaching the thread
Browse files Browse the repository at this point in the history
pthread_setname_np() does not work reliably when a thread has been
created in a detached state. Set the thread name first, and then call
pthread_detach() afterwards (if necessary).

This prevents error messages like this one:
set_thread_name("unixsock conn"): No such process
  • Loading branch information
mkauf committed Oct 3, 2019
1 parent ebb558d commit 6d09c03
Show file tree
Hide file tree
Showing 23 changed files with 58 additions and 84 deletions.
4 changes: 2 additions & 2 deletions src/amqp.c
Expand Up @@ -683,8 +683,8 @@ static int camqp_subscribe_init(camqp_config_t *conf) /* {{{ */
tmp = subscriber_threads + subscriber_threads_num;
memset(tmp, 0, sizeof(*tmp));

status = plugin_thread_create(tmp, /* attr = */ NULL, camqp_subscribe_thread,
conf, "amqp subscribe");
status =
plugin_thread_create(tmp, camqp_subscribe_thread, conf, "amqp subscribe");
if (status != 0) {
ERROR("amqp plugin: pthread_create failed: %s", STRERROR(status));
return status;
Expand Down
5 changes: 2 additions & 3 deletions src/amqp1.c
Expand Up @@ -735,9 +735,8 @@ static int amqp1_init(void) /* {{{ */
if (proactor == NULL) {
pthread_mutex_init(&send_lock, /* attr = */ NULL);
/* start_thread */
int status =
plugin_thread_create(&event_thread_id, NULL /* no attributes */,
event_thread, NULL /* no argument */, "handle");
int status = plugin_thread_create(&event_thread_id, event_thread,
NULL /* no argument */, "handle");
if (status != 0) {
ERROR("amqp1 plugin: pthread_create failed: %s", STRERRNO);
} else {
Expand Down
7 changes: 3 additions & 4 deletions src/daemon/plugin.c
Expand Up @@ -2728,9 +2728,8 @@ static void *plugin_thread_start(void *arg) {
return start_routine(plugin_arg);
} /* void *plugin_thread_start */

int plugin_thread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg,
char const *name) {
int plugin_thread_create(pthread_t *thread, void *(*start_routine)(void *),
void *arg, char const *name) {
plugin_thread_t *plugin_thread;

plugin_thread = malloc(sizeof(*plugin_thread));
Expand All @@ -2741,7 +2740,7 @@ int plugin_thread_create(pthread_t *thread, const pthread_attr_t *attr,
plugin_thread->start_routine = start_routine;
plugin_thread->arg = arg;

int ret = pthread_create(thread, attr, plugin_thread_start, plugin_thread);
int ret = pthread_create(thread, NULL, plugin_thread_start, plugin_thread);
if (ret != 0) {
sfree(plugin_thread);
return ret;
Expand Down
5 changes: 2 additions & 3 deletions src/daemon/plugin.h
Expand Up @@ -473,9 +473,8 @@ cdtime_t plugin_get_interval(void);
* Context-aware thread management.
*/

int plugin_thread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg,
char const *name);
int plugin_thread_create(pthread_t *thread, void *(*start_routine)(void *),
void *arg, char const *name);

/*
* Plugins need to implement this
Expand Down
1 change: 0 additions & 1 deletion src/daemon/plugin_mock.c
Expand Up @@ -233,7 +233,6 @@ plugin_ctx_t plugin_set_ctx(plugin_ctx_t ctx) {
cdtime_t plugin_get_interval(void) { return mock_context.interval; }

int plugin_thread_create(__attribute__((unused)) pthread_t *thread,
__attribute__((unused)) const pthread_attr_t *attr,
__attribute__((unused)) void *(*start_routine)(void *),
__attribute__((unused)) void *arg,
__attribute__((unused)) char const *name) {
Expand Down
2 changes: 1 addition & 1 deletion src/dns.c
Expand Up @@ -284,7 +284,7 @@ static int dns_init(void) {
if (listen_thread_init != 0)
return -1;

status = plugin_thread_create(&listen_thread, NULL, dns_child_loop, (void *)0,
status = plugin_thread_create(&listen_thread, dns_child_loop, (void *)0,
"dns listen");
if (status != 0) {
ERROR("dns plugin: pthread_create failed: %s", STRERRNO);
Expand Down
15 changes: 5 additions & 10 deletions src/email.c
Expand Up @@ -428,14 +428,9 @@ static void *open_connection(void __attribute__((unused)) * arg) {
}

{ /* initialize collector threads */
pthread_attr_t ptattr;

conns.head = NULL;
conns.tail = NULL;

pthread_attr_init(&ptattr);
pthread_attr_setdetachstate(&ptattr, PTHREAD_CREATE_DETACHED);

available_collectors = max_conns;

collectors = smalloc(max_conns * sizeof(*collectors));
Expand All @@ -444,14 +439,14 @@ static void *open_connection(void __attribute__((unused)) * arg) {
collectors[i] = smalloc(sizeof(*collectors[i]));
collectors[i]->socket = NULL;

if (plugin_thread_create(&collectors[i]->thread, &ptattr, collect,
collectors[i], "email collector") != 0) {
if (plugin_thread_create(&collectors[i]->thread, collect, collectors[i],
"email collector") == 0) {
pthread_detach(collectors[i]->thread);
} else {
log_err("plugin_thread_create() failed: %s", STRERRNO);
collectors[i]->thread = (pthread_t)0;
}
}

pthread_attr_destroy(&ptattr);
}

while (1) {
Expand Down Expand Up @@ -523,7 +518,7 @@ static void *open_connection(void __attribute__((unused)) * arg) {
} /* static void *open_connection (void *) */

static int email_init(void) {
if (plugin_thread_create(&connector, NULL, open_connection, NULL,
if (plugin_thread_create(&connector, open_connection, NULL,
"email listener") != 0) {
disabled = 1;
log_err("plugin_thread_create() failed: %s", STRERRNO);
Expand Down
22 changes: 9 additions & 13 deletions src/exec.c
Expand Up @@ -834,7 +834,6 @@ static int exec_read(void) /* {{{ */
{
for (program_list_t *pl = pl_head; pl != NULL; pl = pl->next) {
pthread_t t;
pthread_attr_t attr;

/* Only execute `normal' style executables here. */
if ((pl->flags & PL_NORMAL) == 0)
Expand All @@ -849,14 +848,13 @@ static int exec_read(void) /* {{{ */
pl->flags |= PL_RUNNING;
pthread_mutex_unlock(&pl_lock);

pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int status =
plugin_thread_create(&t, &attr, exec_read_one, (void *)pl, "exec read");
if (status != 0) {
plugin_thread_create(&t, exec_read_one, (void *)pl, "exec read");
if (status == 0) {
pthread_detach(t);
} else {
ERROR("exec plugin: plugin_thread_create failed.");
}
pthread_attr_destroy(&attr);
} /* for (pl) */

return 0;
Expand All @@ -868,7 +866,6 @@ static int exec_notification(const notification_t *n, /* {{{ */

for (program_list_t *pl = pl_head; pl != NULL; pl = pl->next) {
pthread_t t;
pthread_attr_t attr;

/* Only execute `notification' style executables here. */
if ((pl->flags & PL_NOTIF_ACTION) == 0)
Expand All @@ -892,14 +889,13 @@ static int exec_notification(const notification_t *n, /* {{{ */
pln->n.meta = NULL;
plugin_notification_meta_copy(&pln->n, n);

pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int status = plugin_thread_create(&t, &attr, exec_notification_one,
(void *)pln, "exec notify");
if (status != 0) {
int status = plugin_thread_create(&t, exec_notification_one, (void *)pln,
"exec notify");
if (status == 0) {
pthread_detach(t);
} else {
ERROR("exec plugin: plugin_thread_create failed.");
}
pthread_attr_destroy(&attr);
} /* for (pl) */

return 0;
Expand Down
5 changes: 2 additions & 3 deletions src/gmond.c
Expand Up @@ -789,9 +789,8 @@ static int mc_receive_thread_start(void) /* {{{ */

mc_receive_thread_loop = 1;

status =
plugin_thread_create(&mc_receive_thread_id, /* attr = */ NULL,
mc_receive_thread, /* args = */ NULL, "gmond recv");
status = plugin_thread_create(&mc_receive_thread_id, mc_receive_thread,
/* args = */ NULL, "gmond recv");
if (status != 0) {
ERROR("gmond plugin: Starting receive thread failed.");
mc_receive_thread_loop = 0;
Expand Down
3 changes: 1 addition & 2 deletions src/gps.c
Expand Up @@ -287,8 +287,7 @@ static int cgps_init(void) {
CDTIME_T_TO_DOUBLE(cgps_config_data.timeout),
CDTIME_T_TO_DOUBLE(cgps_config_data.pause_connect));

status =
plugin_thread_create(&cgps_thread_id, NULL, cgps_thread, NULL, "gps");
status = plugin_thread_create(&cgps_thread_id, cgps_thread, NULL, "gps");
if (status != 0) {
ERROR("gps plugin: pthread_create() failed.");
return -1;
Expand Down
3 changes: 1 addition & 2 deletions src/ipmi.c
Expand Up @@ -1275,8 +1275,7 @@ static int c_ipmi_init(void) {
st->init_in_progress = cycles;
st->active = true;

status = plugin_thread_create(&st->thread_id, /* attr = */ NULL,
c_ipmi_thread_main,
status = plugin_thread_create(&st->thread_id, c_ipmi_thread_main,
/* user data = */ (void *)st, "ipmi");

if (status != 0) {
Expand Down
4 changes: 2 additions & 2 deletions src/mcelog.c
Expand Up @@ -636,8 +636,8 @@ static int mcelog_init(void) {
}

if (strlen(socket_adapter.unix_sock.sun_path)) {
if (plugin_thread_create(&g_mcelog_config.tid, NULL, poll_worker, NULL,
NULL) != 0) {
if (plugin_thread_create(&g_mcelog_config.tid, poll_worker, NULL, NULL) !=
0) {
ERROR(MCELOG_PLUGIN ": Error creating poll thread.");
return -1;
}
Expand Down
1 change: 0 additions & 1 deletion src/mqtt.c
Expand Up @@ -744,7 +744,6 @@ static int mqtt_init(void) {
continue;

status = plugin_thread_create(&subscribers[i]->thread,
/* attrs = */ NULL,
/* func = */ subscribers_thread,
/* args = */ subscribers[i],
/* name = */ "mqtt");
Expand Down
10 changes: 4 additions & 6 deletions src/network.c
Expand Up @@ -3223,9 +3223,8 @@ static int network_init(void) {

if (dispatch_thread_running == 0) {
int status;
status = plugin_thread_create(&dispatch_thread_id, NULL /* no attributes */,
dispatch_thread, NULL /* no argument */,
"network disp");
status = plugin_thread_create(&dispatch_thread_id, dispatch_thread,
NULL /* no argument */, "network disp");
if (status != 0) {
ERROR("network: pthread_create failed: %s", STRERRNO);
} else {
Expand All @@ -3235,9 +3234,8 @@ static int network_init(void) {

if (receive_thread_running == 0) {
int status;
status = plugin_thread_create(&receive_thread_id, NULL /* no attributes */,
receive_thread, NULL /* no argument */,
"network recv");
status = plugin_thread_create(&receive_thread_id, receive_thread,
NULL /* no argument */, "network recv");
if (status != 0) {
ERROR("network: pthread_create failed: %s", STRERRNO);
} else {
Expand Down
3 changes: 1 addition & 2 deletions src/pinba.c
Expand Up @@ -574,8 +574,7 @@ static int plugin_init(void) /* {{{ */
if (collector_thread_running)
return 0;

status = plugin_thread_create(&collector_thread_id,
/* attrs = */ NULL, collector_thread,
status = plugin_thread_create(&collector_thread_id, collector_thread,
/* args = */ NULL, "pinba collector");
if (status != 0) {
ERROR("pinba plugin: pthread_create(3) failed: %s", STRERRNO);
Expand Down
2 changes: 1 addition & 1 deletion src/ping.c
Expand Up @@ -359,7 +359,7 @@ static int start_thread(void) /* {{{ */

ping_thread_loop = 1;
ping_thread_error = 0;
status = plugin_thread_create(&ping_thread_id, /* attr = */ NULL, ping_thread,
status = plugin_thread_create(&ping_thread_id, ping_thread,
/* arg = */ (void *)0, "ping");
if (status != 0) {
ping_thread_loop = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/procevent.c
Expand Up @@ -1006,7 +1006,7 @@ static int start_netlink_thread(void) /* {{{ */
procevent_netlink_thread_loop = 1;
procevent_netlink_thread_error = 0;

status = plugin_thread_create(&procevent_netlink_thread_id, /* attr = */ NULL,
status = plugin_thread_create(&procevent_netlink_thread_id,
procevent_netlink_thread,
/* arg = */ (void *)0, "procevent");
if (status != 0) {
Expand Down Expand Up @@ -1043,7 +1043,7 @@ static int start_dequeue_thread(void) /* {{{ */
procevent_dequeue_thread_loop = 1;

int status = plugin_thread_create(&procevent_dequeue_thread_id,
/* attr = */ NULL, procevent_dequeue_thread,
procevent_dequeue_thread,
/* arg = */ (void *)0, "procevent");
if (status != 0) {
procevent_dequeue_thread_loop = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/python.c
Expand Up @@ -1170,7 +1170,7 @@ static int cpy_init(void) {
ERROR("python: Unable to create pipe.");
return 1;
}
if (plugin_thread_create(&thread, NULL, cpy_interactive, pipefd + 1,
if (plugin_thread_create(&thread, cpy_interactive, pipefd + 1,
"python interpreter")) {
ERROR("python: Error creating thread for interactive interpreter.");
}
Expand Down
5 changes: 2 additions & 3 deletions src/rrdtool.c
Expand Up @@ -1057,9 +1057,8 @@ static int rrd_init(void) {

pthread_mutex_unlock(&cache_lock);

int status =
plugin_thread_create(&queue_thread, /* attr = */ NULL, rrd_queue_thread,
/* args = */ NULL, "rrdtool queue");
int status = plugin_thread_create(&queue_thread, rrd_queue_thread,
/* args = */ NULL, "rrdtool queue");
if (status != 0) {
ERROR("rrdtool plugin: Cannot create queue-thread.");
return -1;
Expand Down
4 changes: 2 additions & 2 deletions src/sigrok.c
Expand Up @@ -337,8 +337,8 @@ static int sigrok_init(void) {
return -1;
}

status = plugin_thread_create(&sr_thread, NULL, sigrok_read_thread, NULL,
"sigrok read");
status =
plugin_thread_create(&sr_thread, sigrok_read_thread, NULL, "sigrok read");
if (status != 0) {
ERROR("sigrok plugin: Failed to create thread: %s.", STRERRNO);
return -1;
Expand Down
12 changes: 6 additions & 6 deletions src/sysevent.c
Expand Up @@ -754,9 +754,9 @@ static int start_socket_thread(void) /* {{{ */

DEBUG("sysevent plugin: starting socket thread");

int status = plugin_thread_create(&sysevent_socket_thread_id,
/* attr = */ NULL, sysevent_socket_thread,
/* arg = */ (void *)0, "sysevent");
int status =
plugin_thread_create(&sysevent_socket_thread_id, sysevent_socket_thread,
/* arg = */ (void *)0, "sysevent");
if (status != 0) {
sysevent_socket_thread_loop = 0;
ERROR("sysevent plugin: starting socket thread failed.");
Expand All @@ -780,9 +780,9 @@ static int start_dequeue_thread(void) /* {{{ */

sysevent_dequeue_thread_loop = 1;

int status = plugin_thread_create(&sysevent_dequeue_thread_id,
/* attr = */ NULL, sysevent_dequeue_thread,
/* arg = */ (void *)0, "ssyevent");
int status =
plugin_thread_create(&sysevent_dequeue_thread_id, sysevent_dequeue_thread,
/* arg = */ (void *)0, "ssyevent");
if (status != 0) {
sysevent_dequeue_thread_loop = 0;
ERROR("sysevent plugin: Starting dequeue thread failed.");
Expand Down
16 changes: 6 additions & 10 deletions src/unixsock.c
Expand Up @@ -274,10 +274,6 @@ static void *us_server_thread(void __attribute__((unused)) * arg) {
int status;
int *remote_fd;
pthread_t th;
pthread_attr_t th_attr;

pthread_attr_init(&th_attr);
pthread_attr_setdetachstate(&th_attr, PTHREAD_CREATE_DETACHED);

if (us_open_socket() != 0)
pthread_exit((void *)1);
Expand All @@ -293,7 +289,6 @@ static void *us_server_thread(void __attribute__((unused)) * arg) {
ERROR("unixsock plugin: accept failed: %s", STRERRNO);
close(sock_fd);
sock_fd = -1;
pthread_attr_destroy(&th_attr);
pthread_exit((void *)1);
}

Expand All @@ -307,9 +302,11 @@ static void *us_server_thread(void __attribute__((unused)) * arg) {

DEBUG("Spawning child to handle connection on fd #%i", *remote_fd);

status = plugin_thread_create(&th, &th_attr, us_handle_client,
(void *)remote_fd, "unixsock conn");
if (status != 0) {
status = plugin_thread_create(&th, us_handle_client, (void *)remote_fd,
"unixsock conn");
if (status == 0) {
pthread_detach(th);
} else {
WARNING("unixsock plugin: pthread_create failed: %s", STRERRNO);
close(*remote_fd);
free(remote_fd);
Expand All @@ -319,7 +316,6 @@ static void *us_server_thread(void __attribute__((unused)) * arg) {

close(sock_fd);
sock_fd = -1;
pthread_attr_destroy(&th_attr);

status = unlink((sock_file != NULL) ? sock_file : US_DEFAULT_PATH);
if (status != 0) {
Expand Down Expand Up @@ -371,7 +367,7 @@ static int us_init(void) {

loop = 1;

status = plugin_thread_create(&listen_thread, NULL, us_server_thread, NULL,
status = plugin_thread_create(&listen_thread, us_server_thread, NULL,
"unixsock listen");
if (status != 0) {
ERROR("unixsock plugin: pthread_create failed: %s", STRERRNO);
Expand Down

0 comments on commit 6d09c03

Please sign in to comment.