@cryptotaxi247 / netdata-1 / commits / adcc8e8a6

properly cleanup all threads on exit

Costa Tsaousis (ktsaou) committed May 20, 2014 at 01:58 UTC adcc8e8a6906c8e1955e71d37d9c5a3c5c5b9b5a
1 file changed +128 -25
netdata.c
+128 -25
@@ -1686,6 +1686,10 @@ void rrd_stats_next_plugins(RRD_STATS *st)
1686 unsigned long long rrd_stats_done(RRD_STATS *st)
1687 {
1688 RRD_DIMENSION *rd, *last;
1689 + int oldstate;
1690 +
1691 + if(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) != 0)
1692 + error("Cannot set pthread cancel state to DISABLE.");
1693
1694 // a read lock is OK here
1695 pthread_rwlock_rdlock(&st->rwlock);
@@ -1705,6 +1709,10 @@ unsigned long long rrd_stats_done(RRD_STATS *st)
1709 if(st->debug) debug(D_RRD_STATS, "%s: Skipping collected values (usec since last update = %llu, counter_done = %lu)", st->name, st->usec_since_last_update, st->counter_done);
1710 // we don't have any usable data yet
1711 pthread_rwlock_unlock(&st->rwlock);
1712 +
1713 + if(pthread_setcancelstate(oldstate, NULL) != 0)
1714 + error("Cannot set pthread cancel state to RESTORE (%d).", oldstate);
1715 +
1716 return(st->usec_since_last_update);
1717 }
1718
@@ -1973,6 +1981,10 @@ unsigned long long rrd_stats_done(RRD_STATS *st)
1981 }
1982
1983 pthread_rwlock_unlock(&st->rwlock);
1984 +
1985 + if(pthread_setcancelstate(oldstate, NULL) != 0)
1986 + error("Cannot set pthread cancel state to RESTORE (%d).", oldstate);
1987 +
1988 return(st->usec_since_last_update);
1989 }
1990
@@ -3785,6 +3797,12 @@ long web_client_receive(struct web_client *w)
3797
3798 void *new_client(void *ptr)
3799 {
3800 + if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
3801 + error("Cannot set pthread cancel type to DEFERRED.");
3802 +
3803 + if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
3804 + error("Cannot set pthread cancel state to ENABLE.");
3805 +
3806 struct timeval tv;
3807 struct web_client *w = ptr;
3808 int retval;
@@ -5835,6 +5853,13 @@ int do_proc_vmstat() {
5853 void *proc_main(void *ptr)
5854 {
5855 if(ptr) { ; }
5856 +
5857 + if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
5858 + error("Cannot set pthread cancel type to DEFERRED.");
5859 +
5860 + if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
5861 + error("Cannot set pthread cancel state to ENABLE.");
5862 +
5863 struct rusage me, me_last;
5864 struct timeval last, now;
5865
@@ -6149,6 +6174,13 @@ pid_t tc_child_pid = 0;
6174 void *tc_main(void *ptr)
6175 {
6176 if(ptr) { ; }
6177 +
6178 + if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
6179 + error("Cannot set pthread cancel type to DEFERRED.");
6180 +
6181 + if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
6182 + error("Cannot set pthread cancel state to ENABLE.");
6183 +
6184 char buffer[TC_LINE_MAX+1] = "";
6185
6186 for(;1;) {
@@ -6176,10 +6208,16 @@ void *tc_main(void *ptr)
6208
6209 if(strcmp(p, "END") == 0) {
6210 if(device) {
6211 + if(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) != 0)
6212 + error("Cannot set pthread cancel state to DISABLE.");
6213 +
6214 tc_device_commit(device);
6215 tc_device_free(device);
6216 device = NULL;
6217 class = NULL;
6218 +
6219 + if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
6220 + error("Cannot set pthread cancel state to ENABLE.");
6221 }
6222 }
6223 else if(strcmp(p, "BEGIN") == 0) {
@@ -6278,15 +6316,28 @@ void *tc_main(void *ptr)
6316 void *cpuidlejitter_main(void *ptr)
6317 {
6318 if(ptr) { ; }
6319 +
6320 + if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
6321 + error("Cannot set pthread cancel type to DEFERRED.");
6322 +
6323 + if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
6324 + error("Cannot set pthread cancel state to ENABLE.");
6325 +
6326 int sleep_ms = config_get_number("plugin:idlejitter", "loop time in ms", CPU_IDLEJITTER_SLEEP_TIME_MS);
6327 if(sleep_ms <= 0) {
6328 config_set_number("plugin:idlejitter", "loop time in ms", CPU_IDLEJITTER_SLEEP_TIME_MS);
6329 sleep_ms = CPU_IDLEJITTER_SLEEP_TIME_MS;
6330 }
6331
6287 - struct timeval before, after;
6332 + RRD_STATS *st = rrd_stats_find("system.idlejitter");
6333 + if(!st) {
6334 + st = rrd_stats_create("system", "idlejitter", NULL, "cpu", "CPU Idle Jitter", "microseconds lost/s", 9999, update_every, CHART_TYPE_LINE);
6335 + rrd_stats_dimension_add(st, "jitter", NULL, 1, 1, RRD_DIMENSION_ABSOLUTE);
6336 + }
6337
6289 - while(1) {
6338 + struct timeval before, after;
6339 + unsigned long long counter;
6340 + for(counter = 0; 1 ;counter++) {
6341 unsigned long long usec = 0, susec = 0;
6342
6343 while(susec < (update_every * 1000000ULL)) {
@@ -6301,14 +6352,7 @@ void *cpuidlejitter_main(void *ptr)
6352 }
6353 usec -= (sleep_ms * 1000);
6354
6304 - RRD_STATS *st = rrd_stats_find("system.idlejitter");
6305 - if(!st) {
6306 - st = rrd_stats_create("system", "idlejitter", NULL, "cpu", "CPU Idle Jitter", "microseconds lost/s", 9999, update_every, CHART_TYPE_LINE);
6307 -
6308 - rrd_stats_dimension_add(st, "jitter", NULL, 1, 1, RRD_DIMENSION_ABSOLUTE);
6309 - }
6310 - else rrd_stats_next_usec(st, susec);
6311 -
6355 + if(counter) rrd_stats_next_usec(st, susec);
6356 rrd_stats_dimension_set(st, "jitter", usec);
6357 rrd_stats_done(st);
6358 }
@@ -6322,6 +6366,13 @@ void *cpuidlejitter_main(void *ptr)
6366 void *checks_main(void *ptr)
6367 {
6368 if(ptr) { ; }
6369 +
6370 + if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
6371 + error("Cannot set pthread cancel type to DEFERRED.");
6372 +
6373 + if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
6374 + error("Cannot set pthread cancel state to ENABLE.");
6375 +
6376 unsigned long long usec = 0, susec = update_every * 1000000ULL, loop_usec = 0, total_susec = 0;
6377 struct timeval now, last, loop;
6378
@@ -6724,6 +6775,13 @@ void *pluginsd_worker_thread(void *arg)
6775 void *pluginsd_main(void *ptr)
6776 {
6777 if(ptr) { ; }
6778 +
6779 + if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
6780 + error("Cannot set pthread cancel type to DEFERRED.");
6781 +
6782 + if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
6783 + error("Cannot set pthread cancel state to ENABLE.");
6784 +
6785 char *dir_name = config_get("plugins", "plugins directory", PLUGINS_DIR);
6786 int automatic_run = config_get_boolean("plugins", "enable running new plugins", 0);
6787 int scan_frequency = config_get_number("plugins", "check for new plugins every", 60);
@@ -6819,17 +6877,59 @@ void *pluginsd_main(void *ptr)
6877 // ----------------------------------------------------------------------------
6878 // main and related functions
6879
6880 +pthread_t *p_proc = NULL, *p_tc = NULL, *p_jitter = NULL, *p_pluginsd = NULL, *p_checks = NULL;
6881 +
6882 void kill_childs()
6883 {
6884 + if(p_proc) {
6885 + pthread_cancel(*p_proc);
6886 + pthread_join(*p_proc, NULL);
6887 + p_proc = NULL;
6888 + }
6889 +
6890 + if(p_jitter) {
6891 + pthread_cancel(*p_jitter);
6892 + pthread_join(*p_jitter, NULL);
6893 + p_jitter = NULL;
6894 + }
6895 +
6896 + if(p_checks) {
6897 + pthread_cancel(*p_checks);
6898 + pthread_join(*p_checks, NULL);
6899 + p_checks = NULL;
6900 + }
6901 +
6902 if(tc_child_pid) kill(tc_child_pid, SIGTERM);
6903 tc_child_pid = 0;
6904
6905 + if(p_tc) {
6906 + pthread_cancel(*p_tc);
6907 + pthread_join(*p_tc, NULL);
6908 + p_tc = NULL;
6909 + }
6910 +
6911 + if(p_pluginsd) {
6912 + pthread_cancel(*p_pluginsd);
6913 + pthread_join(*p_pluginsd, NULL);
6914 + p_pluginsd = NULL;
6915 + }
6916 +
6917 struct plugind *cd;
6828 - for(cd = pluginsd_root ; cd ; cd = cd->next)
6918 + for(cd = pluginsd_root ; cd ; cd = cd->next) {
6919 if(cd->pid && !cd->obsolete) {
6920 kill(cd->pid, SIGTERM);
6921 cd->pid = 0;
6922 }
6923 +
6924 + pthread_cancel(cd->thread);
6925 + pthread_join(cd->thread, NULL);
6926 + }
6927 +
6928 + struct web_client *w;
6929 + for(w = web_clients; w ; w = w->next) {
6930 + pthread_cancel(w->thread);
6931 + pthread_join(w->thread, NULL);
6932 + }
6933 }
6934
6935 void sig_handler(int signo)
@@ -6842,8 +6942,9 @@ void sig_handler(int signo)
6942 case SIGFPE:
6943 case SIGSEGV:
6944 error("Signaled exit (signal %d). Errno: %d (%s)", signo, errno, strerror(errno));
6945 + signal(signo, SIG_IGN);
6946 kill_childs();
6846 - rrd_stats_save_all();
6947 + rrd_stats_free_all();
6948 exit(1);
6949 break;
6950
@@ -7253,40 +7354,42 @@ int main(int argc, char **argv)
7354 // catch all signals
7355 for (i = 1 ; i < 65 ;i++) if(i != SIGSEGV && i != SIGFPE) signal(i, sig_handler);
7356
7256 -
7257 - pthread_t p_proc, p_tc, p_jitter, p_pluginsd, p_checks;
7258 -
7357 // spawn childs to collect data
7358 if(config_get_boolean("plugins", "tc", 1)) {
7261 - if(pthread_create(&p_tc, NULL, tc_main, NULL))
7359 + p_tc = malloc(sizeof(pthread_t));
7360 + if(pthread_create(p_tc, NULL, tc_main, NULL))
7361 error("failed to create new thread for tc.");
7263 - else if(pthread_detach(p_tc))
7362 + else if(pthread_detach(*p_tc))
7363 error("Cannot request detach of newly created tc thread.");
7364 }
7365
7366 if(config_get_boolean("plugins", "idlejitter", 1)) {
7268 - if(pthread_create(&p_jitter, NULL, cpuidlejitter_main, NULL))
7367 + p_jitter = malloc(sizeof(pthread_t));
7368 + if(pthread_create(p_jitter, NULL, cpuidlejitter_main, NULL))
7369 error("failed to create new thread for idlejitter.");
7270 - else if(pthread_detach(p_jitter))
7370 + else if(pthread_detach(*p_jitter))
7371 error("Cannot request detach of newly created idlejitter thread.");
7372 }
7373
7374 if(config_get_boolean("plugins", "proc", 1)) {
7275 - if(pthread_create(&p_proc, NULL, proc_main, NULL))
7375 + p_proc = malloc(sizeof(pthread_t));
7376 + if(pthread_create(p_proc, NULL, proc_main, NULL))
7377 error("failed to create new thread for proc.");
7277 - else if(pthread_detach(p_proc))
7378 + else if(pthread_detach(*p_proc))
7379 error("Cannot request detach of newly created proc thread.");
7380 }
7381
7281 - if(pthread_create(&p_pluginsd, NULL, pluginsd_main, NULL))
7382 + p_pluginsd = malloc(sizeof(pthread_t));
7383 + if(pthread_create(p_pluginsd, NULL, pluginsd_main, NULL))
7384 error("failed to create new thread for plugins.d.");
7283 - else if(pthread_detach(p_pluginsd))
7385 + else if(pthread_detach(*p_pluginsd))
7386 error("Cannot request detach of newly created plugins.d thread.");
7387
7388 if(config_get_boolean("plugins", "checks", 1)) {
7287 - if(pthread_create(&p_checks, NULL, checks_main, NULL))
7389 + p_checks = malloc(sizeof(pthread_t));
7390 + if(pthread_create(p_checks, NULL, checks_main, NULL))
7391 error("failed to create new thread for checks.");
7289 - else if(pthread_detach(p_checks))
7392 + else if(pthread_detach(*p_checks))
7393 error("Cannot request detach of newly created checks thread.");
7394 }
7395