]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: lua/notification: memory leak
authorThierry FOURNIER <thierry.fournier@ozon.io>
Sun, 10 Dec 2017 16:10:57 +0000 (17:10 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 10 Dec 2017 18:38:58 +0000 (19:38 +0100)
The thread patches adds refcount for notifications. The notifications are
used with the Lua cosocket. These refcount free the notifications when
the session is cleared. In the Lua task case, it not have sessions, so
the nofications are never cleraed.

This patch adds a garbage collector for signals. The garbage collector
just clean the notifications for which the end point is disconnected.

This patch should be backported in 1.8

include/proto/task.h
src/hlua.c

index 1422bf2428abc99eac9606c318bd43c2433eac11..cbc1a9072c7ea416dcfd7d5e32456e5104a6c183 100644 (file)
@@ -326,6 +326,26 @@ static inline void notification_purge(struct list *purge)
        }
 }
 
+/* In some cases, the disconnected notifications must be cleared.
+ * This function just release memory blocs. The purge list is not
+ * locked because it is owned by only one process. Before browsing
+ * this list, the caller must ensure to be the only one browser.
+ * The "com" is not locked because when com->task is NULL, the
+ * notification is no longer used.
+ */
+static inline void notification_gc(struct list *purge)
+{
+       struct notification *com, *back;
+
+       /* Delete all pending communication signals. */
+       list_for_each_entry_safe (com, back, purge, purge_me) {
+               if (com->task)
+                       continue;
+               LIST_DEL(&com->purge_me);
+               pool_free(pool_head_notification, com);
+       }
+}
+
 /* This function sends signals. It wakes all the tasks attached
  * to a list head, and remove the signal, and free the used
  * memory. The wake list is not locked because it is owned by
index 2011c935fa5b06391dedc3b11ce07282b6b53703..2c28e673299e85a61409237ce990af11a3be5555 100644 (file)
@@ -5510,6 +5510,7 @@ static struct task *hlua_process_task(struct task *task)
                break;
 
        case HLUA_E_AGAIN: /* co process or timeout wake me later. */
+               notification_gc(&hlua->com);
                if (hlua->wake_time != TICK_ETERNITY)
                        task->expire = hlua->wake_time;
                break;