From: Willy Tarreau Date: Tue, 21 Apr 2009 00:17:45 +0000 (+0200) Subject: [MEDIUM] ensure we don't recursively call pool_gc2() X-Git-Tag: v1.3.14.13~6 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=d8b199849f1813a8420f1310549921814318a1a7;p=haproxy.git [MEDIUM] ensure we don't recursively call pool_gc2() A race condition exists in the hot reconfiguration code. It is theorically possible that the second signal is sent during a free() in the first list, which can cause crashes or freezes (the later have been observed). Just set up a counter to ensure we do not recurse. (cherry picked from commit b7f9d126e269f3b5b7dc05e39fcf207ba86a330c) (cherry picked from commit 5a01de1c74b8c1c0c2a0e62e9fb6b432e24c79f9) --- diff --git a/src/memory.c b/src/memory.c index 7948bf2ff..1fd8f4429 100644 --- a/src/memory.c +++ b/src/memory.c @@ -120,11 +120,17 @@ void pool_flush2(struct pool_head *pool) /* * This function frees whatever can be freed in all pools, but respecting - * the minimum thresholds imposed by owners. + * the minimum thresholds imposed by owners. It takes care of avoiding + * recursion because it may be called from a signal handler. */ void pool_gc2() { + static int recurse; struct pool_head *entry; + + if (recurse++) + goto out; + list_for_each_entry(entry, &pools, list) { void *temp, *next; //qfprintf(stderr, "Flushing pool %s\n", entry->name); @@ -139,6 +145,8 @@ void pool_gc2() } entry->free_list = next; } + out: + recurse--; } /*