]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Try to fix issue in redis stats backend when task is closed
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 9 Jun 2016 08:30:19 +0000 (09:30 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 9 Jun 2016 08:30:19 +0000 (09:30 +0100)
src/libstat/backends/redis_backend.c

index 4f65a673c80e816f46da17b9e04ae823c3fc7f7a..ea852566e7cefe2d5b2c65d99d7bfaed065d8b89 100644 (file)
@@ -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);
        }
 }