/* wydawca - automatic release submission daemon
Copyright (C) 2008-2013, 2017, 2019-2022 Sergey Poznyakoff
Wydawca is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
Wydawca is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with wydawca. If not, see . */
#include
/* Cumulative statistic counters */
static WY_STAT_COUNTER global_stats[WY_MAX_STAT];
pthread_mutex_t global_stats_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t global_stats_cond = PTHREAD_COND_INITIALIZER;
static int stat_stop;
pthread_t stat_tid;
void
wydawca_stat_add(int what, size_t n)
{
if (what >= WY_MAX_STAT) abort();
pthread_mutex_lock(&global_stats_mutex);
global_stats[what] += n;
pthread_mutex_unlock(&global_stats_mutex);
}
void
wydawca_stat_notify(int final)
{
void *ret;
pthread_mutex_lock(&global_stats_mutex);
stat_stop = final;
pthread_cond_broadcast(&global_stats_cond);
pthread_mutex_unlock(&global_stats_mutex);
if (final)
pthread_join(stat_tid, &ret);
}
static void
stat_reset(void)
{
int i;
for (i = 0; i < WY_MAX_STAT; i++)
global_stats[i] = 0;
}
struct micronent stat_report_schedule;
static void stat_log(void);
static void stat_reset(void);
void *
wy_thr_stat(void *ptr)
{
wy_set_cur_thread_name("WY_stat");
pthread_mutex_lock(&global_stats_mutex);
while (!stat_stop) {
struct timespec ts;
micron_next_time(&stat_report_schedule, &ts);
pthread_cond_timedwait(&global_stats_cond, &global_stats_mutex, &ts);
stat_log();
notify_stat();
stat_reset();
}
pthread_mutex_unlock(&global_stats_mutex);
return NULL;
}
void
wydawca_stat_init(void)
{
pthread_create(&stat_tid, NULL, wy_thr_stat, NULL);
}
static char *stat_name[WY_MAX_STAT] = {
N_("errors"),
N_("warnings"),
N_("bad signatures"),
N_("access violation attempts"),
N_("complete triplets"),
N_("incomplete triplets"),
N_("bad triplets"),
N_("expired triplets"),
N_("triplet successes"),
N_("files uploaded"),
N_("files archived"),
N_("symlinks created"),
N_("symlinks removed"),
N_("check failures"),
};
static char *stat_kwname[WY_MAX_STAT] = {
"stat:errors",
"stat:warnings",
"stat:bad_signatures",
"stat:access_violations",
"stat:complete_triplets",
"stat:incomplete_triplets",
"stat:bad_triplets",
"stat:expired_triplets",
"stat:triplet_success",
"stat:uploads",
"stat:archives",
"stat:symlinks",
"stat:rmsymlinks",
"stat:check_failures"
};
int
wy_stat_mask_p(unsigned long mask)
{
int i;
for (i = 0; i < WY_MAX_STAT; i++)
if (global_stats[i] != 0 && (mask && WY_STAT_MASK(i)))
return 1;
return 0;
}
int
wy_stat_expansion(char **ret, char const *name, size_t len)
{
int i;
for (i = 0; i < WY_MAX_STAT; i++) {
if (strlen(stat_kwname[i]) == len
&& memcmp(stat_kwname[i], name, len) == 0) {
size_t size = 0;
*ret = NULL;
if (grecs_asprintf(ret, &size, "%u", global_stats[i]))
return WRDSE_NOSPACE;
else
return WRDSE_OK;
}
}
return WRDSE_UNDEF;
}
static void
stat_log(void)
{
int i;
if (wy_stat_mask_p(print_stats)) {
for (i = 0; i < WY_MAX_STAT; i++)
if (print_stats & WY_STAT_MASK(i))
wy_log(LOG_INFO, "%s: %u",
gettext(stat_name[i]), global_stats[i]);
}
}