void rctx_armageddon(rctx_t initiator, int exitcode) { unsigned int cursor; rctx_t job; const char *filepos = initiator && initiator->filepos ? initiator->filepos : "(master)"; XBT_DEBUG("Armageddon request by <%s> (exit=%d)", filepos, exitcode); xbt_os_mutex_acquire(armageddon_mutex); if (armageddon_initiator != NULL) { XBT_VERB("Armageddon already started. Let it go"); xbt_os_mutex_release(armageddon_mutex); return; } XBT_DEBUG("Armageddon request by <%s> got the lock. Let's go amok", filepos); armageddon_initiator = initiator; xbt_os_mutex_release(armageddon_mutex); /* Kill foreground command */ if (fg_job) rctx_armageddon_kill_one(initiator, filepos, rctx); /* Kill any background commands */ xbt_dynar_foreach(bg_jobs, cursor, job) { rctx_armageddon_kill_one(initiator, filepos, job); }
static void armageddon_sighandler(int signum) { xbt_os_mutex_acquire(sigwaiter_mutex); caught_signum = signum; armageddon_requested = 1; xbt_os_cond_signal(sigwaiter_cond); xbt_os_mutex_release(sigwaiter_mutex); }
static void *armageddon_sigwaiter(_XBT_GNUC_UNUSED void *arg) { xbt_os_mutex_acquire(sigwaiter_mutex); /* Inform main thread that it started. */ xbt_os_cond_signal(sigwaiter_cond); /* Wait for ending signal... */ xbt_os_cond_wait(sigwaiter_cond, sigwaiter_mutex); if (armageddon_requested) { XBT_ERROR("Test suite `%s': caught signal %d", testsuite_name, caught_signum); rctx_armageddon(rctx, 3); } xbt_os_mutex_release(sigwaiter_mutex); return NULL; }
static void rctx_armageddon_kill_one(rctx_t initiator, const char *filepos, rctx_t rctx) { if (rctx != initiator) { XBT_INFO("Kill <%s> because <%s> failed", rctx->filepos, filepos); xbt_os_mutex_acquire(rctx->interruption); if (!rctx->reader_done) { rctx->interrupted = 1; kill(rctx->pid, SIGTERM); usleep(100); kill(rctx->pid, SIGKILL); } xbt_os_mutex_release(rctx->interruption); } }
static void rctx_armageddon_kill_one(rctx_t initiator, const char *filepos, rctx_t rctx) { if (rctx != initiator) { XBT_INFO("Kill <%s> because <%s> failed", rctx->filepos, filepos); xbt_os_mutex_acquire(rctx->interruption); if (!rctx->reader_done) { rctx->interrupted = 1; kill(rctx->pid, SIGTERM); struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = (100e-6 - floor(100e-6)) * 1e9; nanosleep (&ts, NULL); kill(rctx->pid, SIGKILL); } xbt_os_mutex_release(rctx->interruption); } }
void rctx_init(void) { struct sigaction newact; int i; fg_job = 0; bg_jobs = xbt_dynar_new(sizeof(rctx_t), kill_it); armageddon_mutex = xbt_os_mutex_init(); armageddon_initiator = NULL; sigwaiter_mutex = xbt_os_mutex_init(); sigwaiter_cond = xbt_os_cond_init(); xbt_os_mutex_acquire(sigwaiter_mutex); sigwaiter_thread = xbt_os_thread_create("Armaggedon request waiter", armageddon_sigwaiter, NULL, NULL); /* Wait for thread to start... */ xbt_os_cond_wait(sigwaiter_cond, sigwaiter_mutex); xbt_os_mutex_release(sigwaiter_mutex); memset(&newact, 0, sizeof(newact)); newact.sa_handler = armageddon_sighandler; oldact[0].num = SIGINT; oldact[1].num = SIGQUIT; oldact[2].num = SIGTERM; for (i = 0; i < 3; i++) sigaction(oldact[i].num, &newact, &oldact[i].act); }
/* * This gets called the first time a category is referenced and performs the initialization. * Also resets threshold to inherited! */ int _xbt_log_cat_init(xbt_log_category_t category, e_xbt_log_priority_t priority) { #define _xbt_log_cat_init(a, b) (0) if (log_cat_init_mutex != NULL) xbt_os_mutex_acquire(log_cat_init_mutex); if (category->initialized) { if (log_cat_init_mutex != NULL) xbt_os_mutex_release(log_cat_init_mutex); return priority >= category->threshold; } unsigned int cursor; xbt_log_setting_t setting = NULL; int found = 0; XBT_DEBUG("Initializing category '%s' (firstChild=%s, nextSibling=%s)", category->name, (category->firstChild ? category->firstChild->name : "none"), (category->nextSibling ? category->nextSibling->name : "none")); if (category == &_XBT_LOGV(XBT_LOG_ROOT_CAT)) { category->threshold = xbt_log_priority_info; category->appender = xbt_log_default_appender; category->layout = xbt_log_default_layout; } else { if (!category->parent) category->parent = &_XBT_LOGV(XBT_LOG_ROOT_CAT); XBT_DEBUG("Set %s (%s) as father of %s ", category->parent->name, (category->parent->initialized ? xbt_log_priority_names[category->parent->threshold] : "uninited"), category->name); xbt_log_parent_set(category, category->parent); if (XBT_LOG_ISENABLED(log, xbt_log_priority_debug)) { char *buf, *res = NULL; xbt_log_category_t cpp = category->parent->firstChild; while (cpp) { if (res) { buf = bprintf("%s %s", res, cpp->name); free(res); res = buf; } else { res = xbt_strdup(cpp->name); } cpp = cpp->nextSibling; } XBT_DEBUG("Children of %s: %s; nextSibling: %s", category->parent->name, res, (category->parent->nextSibling ? category->parent->nextSibling->name : "none")); free(res); } } /* Apply the control */ if (xbt_log_settings) { xbt_assert(category, "NULL category"); xbt_assert(category->name); xbt_dynar_foreach(xbt_log_settings, cursor, setting) { xbt_assert(setting, "Damnit, NULL cat in the list"); xbt_assert(setting->catname, "NULL setting(=%p)->catname", (void *) setting); if (!strcmp(setting->catname, category->name)) { found = 1; _xbt_log_cat_apply_set(category, setting); xbt_dynar_cursor_rm(xbt_log_settings, &cursor); } } if (!found) XBT_DEBUG("Category '%s': inherited threshold = %s (=%d)", category->name, xbt_log_priority_names[category->threshold], category->threshold); }