static void analyze_message(hs_analysis_thread* at) { hs_sandbox* sb = NULL; bool sample = at->plugins->sample; int ret; pthread_mutex_lock(&at->list_lock); for (int i = 0; i < at->list_cap; ++i) { if (!at->list[i]) continue; sb = at->list[i]->sb; ret = 0; struct timespec ts, ts1; if (at->msg->msg) { // non idle/empty message if (sample) clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); at->matched = hs_eval_message_matcher(sb->mm, at->msg); if (sample) { clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts1); hs_update_running_stats(&sb->stats.mm, hs_timespec_delta(&ts, &ts1)); } if (at->matched) { ret = hs_process_message(sb->lsb, NULL); if (sample) { clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); hs_update_running_stats(&sb->stats.pm, hs_timespec_delta(&ts1, &ts)); } ++sb->stats.pm_cnt; if (ret < 0) { ++sb->stats.pm_failures; } } } if (ret <= 0 && sb->ticker_interval && at->current_t >= sb->next_timer_event) { clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); ret = hs_timer_event(sb->lsb, at->current_t); clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts1); hs_update_running_stats(&sb->stats.te, hs_timespec_delta(&ts, &ts1)); sb->next_timer_event = at->current_t + sb->ticker_interval; } if (ret > 0) terminate_sandbox(at, i); } pthread_mutex_unlock(&at->list_lock); }
static int output_message(hs_output_plugin* p) { int ret = 0, te_ret = 0; bool sample = p->sample; time_t current_t = time(NULL); p->matched = false; struct timespec ts, ts1; double delta = 0; size_t sequence_id = 0; if (p->msg->msg) { // non idle/empty message double mmdelta = 0; if (sample) clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); p->matched = hs_eval_message_matcher(p->sb->mm, p->msg); if (sample) { clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts1); mmdelta = hs_timespec_delta(&ts, &ts1); } if (p->matched) { if (p->async_len) { sequence_id = p->sb->stats.pm_cnt + 1; int i = sequence_id % p->async_len; p->async_cp[i].input.id = p->cur.input.id; p->async_cp[i].input.offset = p->cur.input.offset; p->async_cp[i].analysis.id = p->cur.analysis.id; p->async_cp[i].analysis.offset = p->cur.analysis.offset; } ret = hs_process_message(p->sb->lsb, (void*)(sequence_id)); if (sample) { clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); delta = hs_timespec_delta(&ts1, &ts); } if (ret <= 0) { pthread_mutex_lock(&p->cp_lock); switch (ret) { case 0: // sent ++p->sb->stats.pm_cnt; p->batching = false; break; case -1: // failure ++p->sb->stats.pm_cnt; ++p->sb->stats.pm_failures; break; case -2: // skip ++p->sb->stats.pm_cnt; break; case -3: // retry break; case -5: // async update if (!p->async_len) { lsb_terminate(p->sb->lsb, "cannot use async checkpointing without" " a configured buffer"); ret = 1; } // fall thru case -4: // batching ++p->sb->stats.pm_cnt; p->batching = true; break; default: lsb_terminate(p->sb->lsb, "invalid process_message return status"); ret = 1; break; } // update the stats if (sample) { hs_update_running_stats(&p->sb->stats.mm, mmdelta); hs_update_running_stats(&p->sb->stats.pm, delta); p->sample = false; mmdelta = 0; } p->sb->stats.cur_memory = lsb_usage(p->sb->lsb, LSB_UT_MEMORY, LSB_US_CURRENT); p->sb->stats.max_memory = lsb_usage(p->sb->lsb, LSB_UT_MEMORY, LSB_US_MAXIMUM); p->sb->stats.max_output = lsb_usage(p->sb->lsb, LSB_UT_OUTPUT, LSB_US_MAXIMUM); p->sb->stats.max_instructions = lsb_usage(p->sb->lsb, LSB_UT_INSTRUCTION, LSB_US_MAXIMUM); pthread_mutex_unlock(&p->cp_lock); if (ret == -1) { const char* err = lsb_get_error(p->sb->lsb); if (strlen(err) > 0) { hs_log(g_module, 4, "file: %s received: %d %s", p->sb->name, ret, lsb_get_error(p->sb->lsb)); } } } } // advance the checkpoint if not batching/async if (ret <= 0 && !p->batching) { pthread_mutex_lock(&p->cp_lock); p->cp.input.id = p->cur.input.id; p->cp.input.offset = p->cur.input.offset; p->cp.analysis.id = p->cur.analysis.id; p->cp.analysis.offset = p->cur.analysis.offset; pthread_mutex_unlock(&p->cp_lock); } if (mmdelta) { pthread_mutex_lock(&p->cp_lock); hs_update_running_stats(&p->sb->stats.mm, mmdelta); p->sample = false; pthread_mutex_unlock(&p->cp_lock); } } if (ret <= 0 && p->sb->ticker_interval && current_t >= p->sb->next_timer_event) { clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); te_ret = hs_timer_event(p->sb->lsb, current_t); clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts1); delta = hs_timespec_delta(&ts, &ts1); pthread_mutex_lock(&p->cp_lock); hs_update_running_stats(&p->sb->stats.te, delta); pthread_mutex_unlock(&p->cp_lock); p->sb->next_timer_event = current_t + p->sb->ticker_interval; } if (ret > 0 || te_ret > 0) { hs_log(g_module, 3, "terminated: %s msg: %s", p->sb->name, lsb_get_error(p->sb->lsb)); return 1; } return ret; }