event_base_loop (ctx->ev_base, 0);
g_mime_shutdown ();
+ rspamd_stat_close ();
rspamd_http_router_free (ctx->http);
rspamd_log_close (rspamd_main->logger);
exit (EXIT_SUCCESS);
gulong (*inc_learns)(struct rspamd_statfile_runtime *runtime, gpointer ctx);
gulong (*dec_learns)(struct rspamd_statfile_runtime *runtime, gpointer ctx);
ucl_object_t* (*get_stat)(struct rspamd_statfile_runtime *runtime, gpointer ctx);
+ void (*close)(gpointer ctx);
gpointer ctx;
};
gulong rspamd_##name##_learns (struct rspamd_statfile_runtime *runtime, \
gpointer ctx); \
ucl_object_t * rspamd_##name##_get_stat (struct rspamd_statfile_runtime *runtime, \
- gpointer ctx)
+ gpointer ctx); \
+ void rspamd_##name##_close (gpointer ctx)
RSPAMD_STAT_BACKEND_DEF(mmaped_file);
RSPAMD_STAT_BACKEND_DEF(redis);
}
gint
-rspamd_mmaped_file_close (rspamd_mmaped_file_ctx * pool,
+rspamd_mmaped_file_close_file (rspamd_mmaped_file_ctx * pool,
rspamd_mmaped_file_t * file)
{
rspamd_mmaped_file_t *pos;
return 0;
}
-void
-rspamd_mmaped_file_destroy (rspamd_mmaped_file_ctx * pool)
-{
- GHashTableIter it;
- gpointer k, v;
- rspamd_mmaped_file_t *f;
-
- g_hash_table_iter_init (&it, pool->files);
- while (g_hash_table_iter_next (&it, &k, &v)) {
- f = (rspamd_mmaped_file_t *)v;
- rspamd_mmaped_file_close (pool, f);
- }
-
- g_hash_table_destroy (pool->files);
- rspamd_mempool_delete (pool->pool);
-}
-
gpointer
rspamd_mmaped_file_init (struct rspamd_stat_ctx *ctx, struct rspamd_config *cfg)
{
return (gpointer)new;
}
+void
+rspamd_mmaped_file_close (gpointer p)
+{
+ rspamd_mmaped_file_ctx *ctx = (rspamd_mmaped_file_ctx *)p;
+ GHashTableIter it;
+ gpointer k, v;
+ rspamd_mmaped_file_t *mf;
+
+ g_assert (ctx != NULL);
+
+ rspamd_mempool_lock_mutex (ctx->lock);
+ g_hash_table_iter_init (&it, ctx->files);
+
+ while (g_hash_table_iter_next (&it, &k, &v)) {
+ mf = v;
+ rspamd_mmaped_file_close_file (ctx, mf);
+ }
+
+ g_hash_table_unref (ctx->files);
+ rspamd_mempool_unlock_mutex (ctx->lock);
+
+ rspamd_mempool_delete (ctx->pool);
+}
+
gpointer
rspamd_mmaped_file_runtime (struct rspamd_task *task,
struct rspamd_statfile_config *stcf,
");"
"CREATE UNIQUE INDEX IF NOT EXISTS un ON users(name);"
"CREATE UNIQUE INDEX IF NOT EXISTS ln ON languages(name);"
- "PRAGMA user_version=" SQLITE3_SCHEMA_VERSION
+ "PRAGMA user_version=" SQLITE3_SCHEMA_VERSION ";"
"INSERT INTO users(id, name, learns) VALUES(0, '" SQLITE3_DEFAULT "',0);"
"INSERT INTO languages(id, name, learns) VALUES(0, '" SQLITE3_DEFAULT "',0);"
"COMMIT;";
while (curst) {
stf = curst->data;
- if (strcmp (stf->backend, SQLITE3_BACKEND_TYPE) == 0) {
+ if (stf->backend && strcmp (stf->backend, SQLITE3_BACKEND_TYPE) == 0) {
/*
* Check configuration sanity
*/
return (gpointer)new;
}
+void
+rspamd_sqlite3_close (gpointer p)
+{
+ struct rspamd_stat_sqlite3_ctx *ctx = p;
+ struct rspamd_stat_sqlite3_db *bk;
+ GHashTableIter it;
+ gpointer k, v;
+
+ g_hash_table_iter_init (&it, ctx->files);
+
+ while (g_hash_table_iter_next (&it, &k, &v)) {
+ bk = v;
+
+ if (bk->sqlite) {
+ if (bk->in_transaction) {
+ rspamd_sqlite3_run_prstmt (bk, RSPAMD_STAT_BACKEND_TRANSACTION_COMMIT);
+ }
+
+ sqlite3_close (bk->sqlite);
+ rspamd_sqlite3_close_prstmt (bk->prstmt);
+ g_slice_free1 (sizeof (*bk), bk);
+ }
+ }
+
+ g_hash_table_destroy (ctx->files);
+}
+
gpointer
rspamd_sqlite3_runtime (struct rspamd_task *task,
struct rspamd_statfile_config *stcf, gboolean learn, gpointer p)
*/
void rspamd_stat_init (struct rspamd_config *cfg);
+/**
+ * Finalize statistics
+ */
+void rspamd_stat_close (void);
+
/**
* Classify the task specified and insert symbols if needed
* @param task
.total_learns = rspamd_##eltn##_total_learns, \
.inc_learns = rspamd_##eltn##_inc_learns, \
.dec_learns = rspamd_##eltn##_dec_learns, \
- .get_stat = rspamd_##eltn##_get_stat \
+ .get_stat = rspamd_##eltn##_get_stat, \
+ .close = rspamd_##eltn##_close \
}
static struct rspamd_stat_backend stat_backends[] = {
}
}
+void
+rspamd_stat_close (void)
+{
+ guint i;
+
+ g_assert (stat_ctx != NULL);
+
+ for (i = 0; i < stat_ctx->backends_count; i ++) {
+ if (stat_ctx->backends[i].close != NULL) {
+ stat_ctx->backends[i].close (stat_ctx->backends[i].ctx);
+ msg_debug ("closed backend %s", stat_ctx->backends[i].name);
+ }
+ }
+}
+
struct rspamd_stat_ctx *
rspamd_stat_get_ctx (void)
{
msg_info ("terminating...");
rspamd_symbols_cache_destroy (rspamd_main->cfg->cache);
+ rspamd_stat_close ();
rspamd_log_close (rspamd_main->logger);
rspamd_config_free (rspamd_main->cfg);
g_free (rspamd_main->cfg);
event_base_loop (ctx->ev_base, 0);
g_mime_shutdown ();
+ rspamd_stat_close ();
rspamd_log_close (rspamd_main->logger);
if (ctx->key) {