summaryrefslogtreecommitdiffstats
path: root/src/libstat
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-06-09 09:30:19 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-06-09 09:30:19 +0100
commit8b35a3e93355e972cf079901c882ad6cf196ff18 (patch)
tree8106b7e8d3d12facdb926e5258a1f026cc0c4449 /src/libstat
parentd2392c19032a785a96cb32b02043b0ecf4dc6afc (diff)
downloadrspamd-8b35a3e93355e972cf079901c882ad6cf196ff18.tar.gz
rspamd-8b35a3e93355e972cf079901c882ad6cf196ff18.zip
[Fix] Try to fix issue in redis stats backend when task is closed
Diffstat (limited to 'src/libstat')
-rw-r--r--src/libstat/backends/redis_backend.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/src/libstat/backends/redis_backend.c b/src/libstat/backends/redis_backend.c
index 4f65a673c..ea852566e 100644
--- a/src/libstat/backends/redis_backend.c
+++ b/src/libstat/backends/redis_backend.c
@@ -22,6 +22,7 @@
#ifdef WITH_HIREDIS
#include "hiredis.h"
#include "adapters/libevent.h"
+#include "ref.h"
#define REDIS_CTX(p) (struct redis_stat_ctx *)(p)
@@ -64,6 +65,7 @@ struct redis_stat_runtime {
guint64 learned;
gint id;
enum rspamd_redis_connection_state conn_state;
+ ref_entry_t ref;
};
/* Used to get statistics from redis */
@@ -722,6 +724,12 @@ rspamd_redis_connected (redisAsyncContext *c, gpointer r, gpointer priv)
task = rt->task;
+ if (rt->conn_state != RSPAMD_REDIS_CONNECTED) {
+ /* Task has disappeared already */
+ REF_RELEASE (rt);
+ return;
+ }
+
if (c->err == 0) {
if (r != NULL) {
if (G_LIKELY (reply->type == REDIS_REPLY_INTEGER)) {
@@ -748,6 +756,7 @@ rspamd_redis_connected (redisAsyncContext *c, gpointer r, gpointer priv)
rt->learned = val;
rt->conn_state = RSPAMD_REDIS_CONNECTED;
+ REF_RETAIN (rt);
msg_debug_task ("connected to redis server, tokens learned for %s: %uL",
rt->redis_object_expanded, rt->learned);
@@ -765,6 +774,8 @@ rspamd_redis_connected (redisAsyncContext *c, gpointer r, gpointer priv)
rspamd_upstream_fail (rt->selected);
rspamd_session_remove_event (task->s, rspamd_redis_fin, rt);
}
+
+ REF_RELEASE (rt);
}
/* Called when we have received tokens values from redis */
@@ -781,6 +792,12 @@ rspamd_redis_processed (redisAsyncContext *c, gpointer r, gpointer priv)
task = rt->task;
+ if (rt->conn_state != RSPAMD_REDIS_CONNECTED) {
+ /* Task has disappeared already */
+ REF_RELEASE (rt);
+ return;
+ }
+
if (c->err == 0) {
if (r != NULL) {
if (reply->type == REDIS_REPLY_ARRAY) {
@@ -848,6 +865,8 @@ rspamd_redis_processed (redisAsyncContext *c, gpointer r, gpointer priv)
rspamd_upstream_fail (rt->selected);
rspamd_session_remove_event (task->s, rspamd_redis_fin, rt);
}
+
+ REF_RELEASE (rt);
}
/* Called when we have set tokens during learning */
@@ -859,6 +878,12 @@ rspamd_redis_learned (redisAsyncContext *c, gpointer r, gpointer priv)
task = rt->task;
+ if (rt->conn_state != RSPAMD_REDIS_CONNECTED) {
+ /* Task has disappeared already */
+ REF_RELEASE (rt);
+ return;
+ }
+
if (c->err == 0) {
rspamd_upstream_ok (rt->selected);
rspamd_session_remove_event (task->s, rspamd_redis_fin_learn, rt);
@@ -874,6 +899,8 @@ rspamd_redis_learned (redisAsyncContext *c, gpointer r, gpointer priv)
redisAsyncFree (rt->redis);
rt->conn_state = RSPAMD_REDIS_DISCONNECTED;
}
+
+ REF_RELEASE (rt);
}
static gboolean
@@ -1053,6 +1080,12 @@ rspamd_redis_init (struct rspamd_stat_ctx *ctx,
return (gpointer)backend;
}
+static void
+rspamd_redis_runtime_dtor (struct redis_stat_runtime *rt)
+{
+ g_slice_free1 (sizeof (*rt), rt);
+}
+
gpointer
rspamd_redis_runtime (struct rspamd_task *task,
struct rspamd_statfile_config *stcf,
@@ -1090,7 +1123,8 @@ rspamd_redis_runtime (struct rspamd_task *task,
return NULL;
}
- rt = rspamd_mempool_alloc0 (task->task_pool, sizeof (*rt));
+ rt = g_slice_alloc0 (sizeof (*rt));
+ REF_INIT_RETAIN (rt, rspamd_redis_runtime_dtor);
rspamd_redis_expand_object (ctx->redis_object, ctx, task,
&rt->redis_object_expanded);
rt->selected = up;
@@ -1192,6 +1226,8 @@ rspamd_redis_finalize_process (struct rspamd_task *task, gpointer runtime,
rt->redis = NULL;
rt->conn_state = RSPAMD_REDIS_DISCONNECTED;
+
+ REF_RELEASE (rt);
}
}
@@ -1329,6 +1365,7 @@ rspamd_redis_finalize_learn (struct rspamd_task *task, gpointer runtime,
rt->redis = NULL;
rt->conn_state = RSPAMD_REDIS_DISCONNECTED;
+ REF_RELEASE (rt);
}
}