]> git.kaiwu.me - nginx.git/commitdiff
Fixed memory leak on HUP signal when PCRE JIT was used.
authorValentin Bartenev <vbart@nginx.com>
Mon, 30 Jan 2012 12:53:57 +0000 (12:53 +0000)
committerValentin Bartenev <vbart@nginx.com>
Mon, 30 Jan 2012 12:53:57 +0000 (12:53 +0000)
The PCRE JIT compiler uses mmap to allocate memory for its executable codes, so
we have to explicitly call the pcre_free_study() function to free this memory.

src/core/ngx_regex.c

index a7137fe4e2310dda718a39fac62f4e3f084dc31e..677f862bf17a3c73ab5825cb9194f57a4fcf486b 100644 (file)
@@ -16,6 +16,9 @@ typedef struct {
 
 static void * ngx_libc_cdecl ngx_regex_malloc(size_t size);
 static void ngx_libc_cdecl ngx_regex_free(void *p);
+#if (NGX_HAVE_PCRE_JIT)
+static void ngx_pcre_free_studies(void *data);
+#endif
 
 static ngx_int_t ngx_regex_module_init(ngx_cycle_t *cycle);
 
@@ -274,6 +277,41 @@ ngx_regex_free(void *p)
 }
 
 
+#if (NGX_HAVE_PCRE_JIT)
+
+static void
+ngx_pcre_free_studies(void *data)
+{
+    ngx_list_t *studies = data;
+
+    ngx_uint_t        i;
+    ngx_list_part_t  *part;
+    ngx_regex_elt_t  *elts;
+
+    part = &studies->part;
+    elts = part->elts;
+
+    for (i = 0 ; /* void */ ; i++) {
+
+        if (i >= part->nelts) {
+            if (part->next == NULL) {
+                break;
+            }
+
+            part = part->next;
+            elts = part->elts;
+            i = 0;
+        }
+
+        if (elts[i].regex->extra != NULL) {
+            pcre_free_study(elts[i].regex->extra);
+        }
+    }
+}
+
+#endif
+
+
 static ngx_int_t
 ngx_regex_module_init(ngx_cycle_t *cycle)
 {
@@ -287,12 +325,27 @@ ngx_regex_module_init(ngx_cycle_t *cycle)
 
 #if (NGX_HAVE_PCRE_JIT)
     {
-    ngx_regex_conf_t  *rcf;
+    ngx_regex_conf_t    *rcf;
+    ngx_pool_cleanup_t  *cln;
 
     rcf = (ngx_regex_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_regex_module);
 
     if (rcf->pcre_jit) {
         opt = PCRE_STUDY_JIT_COMPILE;
+
+        /*
+         * The PCRE JIT compiler uses mmap for its executable codes, so we
+         * have to explicitly call the pcre_free_study() function to free
+         * this memory.
+         */
+
+        cln = ngx_pool_cleanup_add(cycle->pool, 0);
+        if (cln == NULL) {
+            return NGX_ERROR;
+        }
+
+        cln->handler = ngx_pcre_free_studies;
+        cln->data = ngx_pcre_studies;
     }
     }
 #endif