httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Yann Ylavic <ylavic....@gmail.com>
Subject Re: svn commit: r1599531 - in /httpd/httpd/trunk: CHANGES include/ap_listen.h server/listen.c server/mpm/event/event.c server/mpm/prefork/prefork.c server/mpm/worker/worker.c server/mpm_unix.c
Date Mon, 06 Oct 2014 19:45:29 GMT
Yingqi,

On Mon, Oct 6, 2014 at 6:54 PM, Lu, Yingqi <yingqi.lu@intel.com> wrote:
> My question is: if we do malloc and realloc(), I think it would be just in memory. I
can free() the whole thing on httpd stop. Do you mean that or you actually mean we need create
a new memory pool, allocate/realloc the memory there and register the cleanup on stop?

Either you create a dedicated memory pool for the retained buckets
(actually you may need two pools for the time the previous buckets are
copied to the news ones), and in this case you don't need a cleanup
(the retained pool will be destroyed automatically when httpd exits).

Something like this for mpm_worker :

Index: server/mpm/worker/worker.c
===================================================================
--- server/mpm/worker/worker.c    (revision 1629482)
+++ server/mpm/worker/worker.c    (working copy)
@@ -1804,7 +1804,6 @@ static int worker_run(apr_pool_t *_pconf, apr_pool

     ap_log_pid(pconf, ap_pid_fname);

-    bucket = apr_palloc(_pconf, sizeof(int) *  ap_daemons_limit);
     /* Initialize cross-process accept lock */
     accept_mutex = apr_palloc(_pconf, sizeof(apr_proc_mutex_t *) *
num_buckets);
     for (i = 0; i < num_buckets; i++) {
@@ -1816,6 +1815,28 @@ static int worker_run(apr_pool_t *_pconf, apr_pool
         }
     }

+    if (retained->bucket_pool) {
+        if (retained->daemons_limit < ap_daemons_limit) {
+            apr_pool_t *p;
+            int *new_bucket;
+            apr_pool_create(&p, s->process->pool);
+            new_bucket = apr_palloc(p, sizeof(int) * ap_daemons_limit);
+            memcpy(new_bucket, retained->bucket,
+                   sizeof(int) * retained->daemons_limit);
+            memset(new_bucket + retained->daemons_limit, 0,
+                   sizeof(int) * (ap_daemons_limit - retained->daemons_limit));
+            apr_pool_destroy(retained->bucket_pool);
+            retained->daemons_limit = ap_daemons_limit;
+            retained->bucket = new_bucket;
+            retained->bucket_pool = p;
+        }
+        bucket = apr_pmemdup(_pconf, retained->bucket,
+                             sizeof(int) * retained->daemons_limit);
+    }
+    else {
+        bucket = apr_pcalloc(_pconf, sizeof(int) * ap_daemons_limit);
+    }
+
     if (!retained->is_graceful) {
         if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
             mpm_state = AP_MPMQ_STOPPING;
@@ -1957,6 +1978,15 @@ static int worker_run(apr_pool_t *_pconf, apr_pool
         return DONE;
     }

+    if (!retained->bucket_pool) {
+        apr_pool_t *p;
+        apr_pool_create(&p, s->process->pool);
+        retained->bucket = apr_palloc(p, sizeof(int) * ap_daemons_limit);
+        retained->daemons_limit = ap_daemons_limit;
+        retained->bucket_pool = p;
+    }
+    memcpy(retained->bucket, bucket, sizeof(int) * ap_daemons_limit);
+
     /* advance to the next generation */
     /* XXX: we really need to make sure this new generation number isn't in
      * use by any of the children.
[END]


Or you can use malloc()/realloc() to avoid the double pool situation
with something like (this time with mpm_prefork) :

Index: server/mpm/prefork/prefork.c
===================================================================
--- server/mpm/prefork/prefork.c    (revision 1629482)
+++ server/mpm/prefork/prefork.c    (working copy)
@@ -969,7 +969,6 @@ static int prefork_run(apr_pool_t *_pconf, apr_poo

     ap_log_pid(pconf, ap_pid_fname);

-    bucket = apr_palloc(_pconf, sizeof(int) *  ap_daemons_limit);
     /* Initialize cross-process accept lock for each bucket*/
     accept_mutex = apr_palloc(_pconf, sizeof(apr_proc_mutex_t *) *
num_buckets);
     for (i = 0; i < num_buckets; i++) {
@@ -979,8 +978,27 @@ static int prefork_run(apr_pool_t *_pconf, apr_poo
             mpm_state = AP_MPMQ_STOPPING;
             return DONE;
         }
-     }
+    }

+    if (retained->bucket) {
+        if (retained->daemons_limit < ap_daemons_limit) {
+            retained->bucket = ap_realloc(retained->bucket,
+                                          sizeof(int) * ap_daemons_limit);
+            if (!retained->bucket) {
+                ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
ap_server_conf, APLOGNO()
+                             "could not allocate buckets");
+            }
+            memset(retained->bucket + retained->daemons_limit, 0,
+                   sizeof(int) * (ap_daemons_limit - retained->daemons_limit));
+            retained->daemons_limit = ap_daemons_limit;
+        }
+        bucket = apr_pmemdup(_pconf, retained->bucket,
+                             sizeof(int) * retained->daemons_limit);
+    }
+    else {
+        bucket = apr_pcalloc(_pconf, sizeof(int) * ap_daemons_limit);
+    }
+
     if (!retained->is_graceful) {
         if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
             mpm_state = AP_MPMQ_STOPPING;
@@ -1232,6 +1250,16 @@ static int prefork_run(apr_pool_t *_pconf, apr_poo
         return DONE;
     }

+    if (!retained->bucket) {
+        retained->daemons_limit = ap_daemons_limit;
+        retained->bucket = ap_malloc(sizeof(int) * ap_daemons_limit);
+        if (!retained->bucket) {
+            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, APLOGNO()
+                         "could not allocate buckets");
+        }
+    }
+    memcpy(retained->bucket, bucket, sizeof(int) * ap_daemons_limit);
+
     /* advance to the next generation */
     /* XXX: we really need to make sure this new generation number isn't in
      * use by any of the children.
[END]


Please note that I didn't even try to compile this code, it's just a
quick proof of concept and hence may be bogus in the details.

Regards,
Yann.

Mime
View raw message