aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstat/stat_config.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-01-09 13:33:04 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-01-09 13:33:04 +0000
commitaee3e6a68d84f7ed2047e4b9b939492008b7f7af (patch)
tree89b0a5e2dc0b140829d65c4188d5b5711bb599d4 /src/libstat/stat_config.c
parent6b0f624216ca5c0311a62ae117f56d7cbcb4c840 (diff)
downloadrspamd-aee3e6a68d84f7ed2047e4b9b939492008b7f7af.tar.gz
rspamd-aee3e6a68d84f7ed2047e4b9b939492008b7f7af.zip
Implement async timered events for statistics
Diffstat (limited to 'src/libstat/stat_config.c')
-rw-r--r--src/libstat/stat_config.c67
1 files changed, 62 insertions, 5 deletions
diff --git a/src/libstat/stat_config.c b/src/libstat/stat_config.c
index 319eebaeb..9cdf6af8e 100644
--- a/src/libstat/stat_config.c
+++ b/src/libstat/stat_config.c
@@ -228,11 +228,7 @@ rspamd_stat_close (void)
while (cur) {
aelt = cur->data;
-
- if (aelt->cleanup) {
- aelt->cleanup (aelt, aelt->ud);
- }
-
+ REF_RELEASE (aelt);
cur = g_list_next (cur);
}
@@ -323,3 +319,64 @@ rspamd_stat_get_cache (const gchar *name)
return NULL;
}
+
+static void
+rspamd_async_elt_dtor (struct rspamd_stat_async_elt *elt)
+{
+ if (elt->cleanup) {
+ elt->cleanup (elt, elt->ud);
+ }
+
+ event_del (&elt->timer_ev);
+ g_slice_free1 (sizeof (*elt), elt);
+}
+
+static void
+rspamd_async_elt_on_timer (gint fd, short what, gpointer d)
+{
+ struct rspamd_stat_async_elt *elt = d;
+ gdouble jittered_time;
+
+ event_del (&elt->timer_ev);
+
+ if (elt->enabled) {
+ elt->handler (elt, elt->ud);
+ }
+
+ jittered_time = rspamd_time_jitter (elt->timeout, 0);
+ double_to_tv (jittered_time, &elt->tv);
+ event_add (&elt->timer_ev, &elt->tv);
+}
+
+struct rspamd_stat_async_elt*
+rspamd_stat_ctx_register_async (rspamd_stat_async_handler handler,
+ rspamd_stat_async_cleanup cleanup,
+ gpointer d,
+ gdouble timeout)
+{
+ struct rspamd_stat_async_elt *elt;
+ struct rspamd_stat_ctx *st_ctx;
+ gdouble jittered_time;
+
+ st_ctx = rspamd_stat_get_ctx ();
+ g_assert (st_ctx != NULL);
+
+ elt = g_slice_alloc (sizeof (*elt));
+ REF_INIT_RETAIN (elt, rspamd_async_elt_dtor);
+ elt->handler = handler;
+ elt->cleanup = cleanup;
+ elt->ud = d;
+ elt->timeout = timeout;
+ /* Enabled by default */
+ elt->enabled = TRUE;
+
+ event_set (&elt->timer_ev, -1, EV_TIMEOUT, rspamd_async_elt_on_timer, elt);
+ event_base_set (st_ctx->ev_base, &elt->timer_ev);
+ jittered_time = rspamd_time_jitter (elt->timeout, 0);
+ double_to_tv (jittered_time, &elt->tv);
+ event_add (&elt->timer_ev, &elt->tv);
+
+ g_queue_push_tail (st_ctx->async_elts, elt);
+
+ return elt;
+}