You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by sa...@apache.org on 2006/12/02 17:38:19 UTC

svn commit: r481577 - in /webservices/axis2/trunk/c: modules/core/engine/ modules/core/transport/http/server/apache2/ util/include/ util/src/

Author: samisa
Date: Sat Dec  2 08:38:17 2006
New Revision: 481577

URL: http://svn.apache.org/viewvc?view=rev&rev=481577
Log:
Applied the patch by Chris to fix the memory leaks in httpd module using APR pools.


Modified:
    webservices/axis2/trunk/c/modules/core/engine/ctx_handler.c
    webservices/axis2/trunk/c/modules/core/transport/http/server/apache2/mod_axis2.c
    webservices/axis2/trunk/c/util/include/axis2_allocator.h
    webservices/axis2/trunk/c/util/include/axis2_error.h
    webservices/axis2/trunk/c/util/src/allocator.c
    webservices/axis2/trunk/c/util/src/array_list.c
    webservices/axis2/trunk/c/util/src/dir_handler.c
    webservices/axis2/trunk/c/util/src/env.c
    webservices/axis2/trunk/c/util/src/error.c
    webservices/axis2/trunk/c/util/src/properties.c

Modified: webservices/axis2/trunk/c/modules/core/engine/ctx_handler.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/modules/core/engine/ctx_handler.c?view=diff&rev=481577&r1=481576&r2=481577
==============================================================================
--- webservices/axis2/trunk/c/modules/core/engine/ctx_handler.c (original)
+++ webservices/axis2/trunk/c/modules/core/engine/ctx_handler.c Sat Dec  2 08:38:17 2006
@@ -140,6 +140,7 @@
     else if (op) /*  2. if no op_ctx, create new op_ctx */
     {
         axis2_conf_ctx_t *conf_ctx = NULL;
+        axis2_allocator_switch_to_global_pool(env->allocator);
         op_ctx = axis2_op_ctx_create(env, op, NULL);
         if (!op_ctx)
         {
@@ -154,11 +155,12 @@
         if (conf_ctx)
         {
             svc_grp_ctx = AXIS2_CONF_CTX_FILL_CTXS(conf_ctx, env, msg_ctx);
-            if (svc_grp_ctx)
-                return AXIS2_SUCCESS;
         }
 
+        axis2_allocator_switch_to_local_pool(env->allocator);
     }
 
+    if (!svc_grp_ctx)
+        return AXIS2_FAILURE;
     return AXIS2_SUCCESS;
 }

Modified: webservices/axis2/trunk/c/modules/core/transport/http/server/apache2/mod_axis2.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/modules/core/transport/http/server/apache2/mod_axis2.c?view=diff&rev=481577&r1=481576&r2=481577
==============================================================================
--- webservices/axis2/trunk/c/modules/core/transport/http/server/apache2/mod_axis2.c (original)
+++ webservices/axis2/trunk/c/modules/core/transport/http/server/apache2/mod_axis2.c Sat Dec  2 08:38:17 2006
@@ -17,6 +17,7 @@
 
 #include <httpd.h>
 #include <http_config.h>
+#include <http_log.h>
 #include <http_protocol.h>
 #include <ap_config.h>
 #include <apr_strings.h>
@@ -66,6 +67,18 @@
 axis2_handler(
     request_rec *req);
 
+void *AXIS2_CALL
+axis2_module_malloc(
+    axis2_allocator_t *allocator, size_t size);
+
+void *AXIS2_CALL
+axis2_module_realloc(
+    axis2_allocator_t *allocator, void *ptr, size_t size);
+
+void AXIS2_CALL
+axis2_module_free(
+    axis2_allocator_t *allocator, void *ptr);
+
 static void
 axis2_module_init(
     apr_pool_t* p,
@@ -216,7 +229,10 @@
         return rv;
     }
     ap_should_client_block(req);
+
+    axis2_env->allocator->local_pool = (void*) req->pool;
     rv = AXIS2_APACHE2_WORKER_PROCESS_REQUEST(axis2_worker, axis2_env, req);
+
     if (AXIS2_CRITICAL_FAILURE == rv)
     {
         return HTTP_INTERNAL_SERVER_ERROR;
@@ -224,16 +240,38 @@
     return rv;
 }
 
+void * AXIS2_CALL
+axis2_module_malloc(
+    axis2_allocator_t *allocator, size_t size)
+{
+    return apr_palloc((apr_pool_t*) (allocator->local_pool), size);
+}
+
+void * AXIS2_CALL
+axis2_module_realloc(
+    axis2_allocator_t *allocator, void *ptr, size_t size)
+{
+    /* can't be easily implemented */
+    return NULL;
+}
+
+void AXIS2_CALL
+axis2_module_free(
+    axis2_allocator_t *allocator, void *ptr)
+{
+}
+
 static void
 axis2_module_init(
     apr_pool_t* p,
     server_rec* svr_rec)
 {
+    apr_pool_t *pool;
+    apr_status_t status;
     axis2_allocator_t *allocator = NULL;
     axis2_error_t *error = NULL;
     axis2_log_t *axis2_logger = NULL;
     axis2_thread_pool_t *thread_pool = NULL;
-    axis2_status_t status = AXIS2_SUCCESS;
     axis2_config_rec_t *conf = (axis2_config_rec_t*)ap_get_module_config(
                 svr_rec->module_config, &axis2_module);
 
@@ -241,42 +279,67 @@
      */
     axiom_xml_reader_init();
 
-    /*apr_pool_cleanup_register(p, NULL, module_exit, apr_pool_cleanup_null);*/
-    allocator = axis2_allocator_init(NULL);
-    if (NULL == allocator)
+    /* create an allocator that uses APR memory pools and lasts the
+     * lifetime of the httpd server child process
+     */
+    status = apr_pool_create(&pool, p);
+    if (status)
     {
-        fprintf(stderr, "[Axis2] Error initilizing mod_axis2. Reason :"
-                "allocator init failed\n");
-        status = AXIS2_FAILURE;
+        ap_log_error(APLOG_MARK, APLOG_EMERG, status, svr_rec,
+                     "[Axis2] Error allocating mod_axis2 memory pool");
+        exit(APEXIT_CHILDFATAL);
     }
+    allocator = (axis2_allocator_t*) apr_palloc(pool,
+                                                sizeof(axis2_allocator_t));
+    if (NULL == allocator)
+    {
+        ap_log_error(APLOG_MARK, APLOG_EMERG, APR_ENOMEM, svr_rec,
+                     "[Axis2] Error allocating mod_axis2 allocator");
+        exit(APEXIT_CHILDFATAL);
+    }
+    allocator->malloc_fn = axis2_module_malloc;
+    allocator->realloc = axis2_module_realloc;
+    allocator->free_fn = axis2_module_free;
+    allocator->local_pool = (void*) pool;
+    allocator->global_pool = (void*) pool;
+
+    if (NULL == allocator)
+    {
+        ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+                         "[Axis2] Error initializing mod_axis2 allocator");
+        exit(APEXIT_CHILDFATAL);
+    }
+    
+    axis2_error_init();
+    
     error = axis2_error_create(allocator);
     if (NULL == error)
     {
-        fprintf(stderr, "[Axis2] Error initilizing mod_axis2. Reason :"
-                "error struct creation failed\n");
-        status = AXIS2_FAILURE;
+        ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+                     "[Axis2] Error creating mod_axis2 error structure");
+        exit(APEXIT_CHILDFATAL);
     }
     axis2_logger = axis2_log_create(allocator, NULL, conf->axis2_log_file);
     if (NULL == axis2_logger)
     {
-        fprintf(stderr, "[Axis2] Error initilizing mod_axis2. Reason :"
-                "log init failed\n");
-        status = AXIS2_FAILURE;
+        ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+                     "[Axis2] Error creating mod_axis2 log structure");
+        exit(APEXIT_CHILDFATAL);
     }
     thread_pool = axis2_thread_pool_init(allocator);
     if (NULL == thread_pool)
     {
-        fprintf(stderr, "[Axis2] Error initilizing mod_axis2. Reason :"
-                "thread_pool init failed\n");
-        status = AXIS2_FAILURE;
+        ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+                     "[Axis2] Error initializing mod_axis2 thread pool");
+        exit(APEXIT_CHILDFATAL);
     }
     axis2_env = axis2_env_create_with_error_log_thread_pool(allocator, error,
             axis2_logger, thread_pool);
     if (NULL == axis2_env)
     {
-        fprintf(stderr, "[Axis2] Error initilizing mod_axis2. Reason :"
-                "axis2_environment init failed\n");
-        status = AXIS2_FAILURE;
+        ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+                     "[Axis2] Error creating mod_axis2 environment");
+        exit(APEXIT_CHILDFATAL);
     }
     if (axis2_logger)
     {
@@ -289,14 +352,8 @@
             conf->axis2_repo_path);
     if (NULL == axis2_worker)
     {
-        fprintf(stderr, "[Axis2] Error initilizing mod_axis2. Reason :"
-                "axis2_worker init failed\n");
-        status = AXIS2_FAILURE;
-    }
-    if (AXIS2_FAILURE == status)
-    {
-        fprintf(stderr, "[Axis2] Due to one or more errors mod_axis2 loading"
-                " failed. Causing apache2 to stop loading\n");
+        ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+                     "[Axis2] Error creating mod_axis2 apache2 worker");
         exit(APEXIT_CHILDFATAL);
     }
 }

Modified: webservices/axis2/trunk/c/util/include/axis2_allocator.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/util/include/axis2_allocator.h?view=diff&rev=481577&r1=481576&r2=481577
==============================================================================
--- webservices/axis2/trunk/c/util/include/axis2_allocator.h (original)
+++ webservices/axis2/trunk/c/util/include/axis2_allocator.h Sat Dec  2 08:38:17 2006
@@ -74,6 +74,10 @@
         * @param ptr pointer to be freed
         */
          void (AXIS2_CALL *free_fn) (struct axis2_allocator *allocator, void *ptr);
+        /** local memory pool */
+         void *local_pool;
+        /** global memory pool */
+         void *global_pool;
     } axis2_allocator_t;
 
   /**
@@ -82,7 +86,7 @@
     * @return initialized allocator. NULL on error.
     */
     AXIS2_EXTERN axis2_allocator_t * AXIS2_CALL 
-   axis2_allocator_init (axis2_allocator_t *allocator);
+    axis2_allocator_init (axis2_allocator_t *allocator);
 
   /** 
     * This function should be used to deallocate memory if the default allocator provided by
@@ -90,7 +94,29 @@
     * @param allocator 
     */
     AXIS2_EXTERN axis2_status_t AXIS2_CALL 
-   axis2_allocator_free(axis2_allocator_t *allocator);
+    axis2_allocator_free(axis2_allocator_t *allocator);
+
+  /** 
+    * Swaps the local_pool and global_pool values. 
+    * In case of using pools, local_pool is suppoed to hold the pool out of which
+    * local values are allocated. In case of values that live beyond a request 
+    * globle pool should be used, hence this method has to be called to swithch to 
+    * globle pool for allocation. 
+    * @param allocator allocator whose memory pools are to be switched
+    */
+    AXIS2_EXTERN void AXIS2_CALL 
+    axis2_allocator_switch_to_global_pool(axis2_allocator_t *allocator);
+
+  /** 
+    * Swaps the local_pool and global_pool values. 
+    * In case of using pools, local_pool is suppoed to hold the pool out of which
+    * local values are allocated. In case of values that live beyond a request 
+    * globle pool should be used. This method can be used to inverse the switching 
+    * done by axis2_allocator_switch_to_global_pool, to start using the local pool again.
+    * @param allocator allocator whose memory pools are to be switched
+    */
+    AXIS2_EXTERN void AXIS2_CALL 
+    axis2_allocator_switch_to_local_pool(axis2_allocator_t *allocator);
 
 #define AXIS2_MALLOC(allocator, size) \
       ((allocator)->malloc_fn(allocator, size))

Modified: webservices/axis2/trunk/c/util/include/axis2_error.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/util/include/axis2_error.h?view=diff&rev=481577&r1=481576&r2=481577
==============================================================================
--- webservices/axis2/trunk/c/util/include/axis2_error.h (original)
+++ webservices/axis2/trunk/c/util/include/axis2_error.h Sat Dec  2 08:38:17 2006
@@ -527,6 +527,22 @@
         /** Invalid parameters for service operation in SOAP request */
         AXIS2_ERROR_SVC_SKEL_INVALID_OPERATION_PARAMETERS_IN_SOAP_REQUEST,
         
+       /*
+        * Group - repos
+        */
+        /* not authenticated */
+        AXIS2_ERROR_REPOS_NOT_AUTHENTICATED,
+        /* unsupported mode */
+        AXIS2_ERROR_REPOS_UNSUPPORTED_MODE,
+        /* expired */
+        AXIS2_ERROR_REPOS_EXPIRED,
+        /* not implemented */
+        AXIS2_ERROR_REPOS_NOT_IMPLEMENTED,
+        /* not found */
+        AXIS2_ERROR_REPOS_NOT_FOUND,
+        /* bad search text */
+        AXIS2_ERROR_REPOS_BAD_SEARCH_TEXT,
+
         /** The following has to be the last error value all the time.
             All other error codes should appear above this.
             AXIS2_ERROR_LAST is used to track the number of error codes present
@@ -599,6 +615,7 @@
     {
         /** error related ops */
         struct axis2_error_ops *ops;
+        axis2_allocator_t *allocator;
         /** last error number */
         int error_number;
 

Modified: webservices/axis2/trunk/c/util/src/allocator.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/util/src/allocator.c?view=diff&rev=481577&r1=481576&r2=481577
==============================================================================
--- webservices/axis2/trunk/c/util/src/allocator.c (original)
+++ webservices/axis2/trunk/c/util/src/allocator.c Sat Dec  2 08:38:17 2006
@@ -75,3 +75,26 @@
 {
     free(ptr);
 }
+
+
+AXIS2_EXTERN void AXIS2_CALL 
+axis2_allocator_switch_to_global_pool(axis2_allocator_t *allocator)
+{
+    if (!allocator)
+        return;
+    void *temp = allocator->local_pool;
+    allocator->local_pool = allocator->global_pool;
+    allocator->global_pool = temp;
+    return;
+}
+
+AXIS2_EXTERN void AXIS2_CALL 
+axis2_allocator_switch_to_local_pool(axis2_allocator_t *allocator)
+{
+    if (!allocator)
+        return;
+    void *temp = allocator->global_pool;
+    allocator->global_pool = allocator->local_pool;
+    allocator->local_pool = temp;
+    return;
+}

Modified: webservices/axis2/trunk/c/util/src/array_list.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/util/src/array_list.c?view=diff&rev=481577&r1=481576&r2=481577
==============================================================================
--- webservices/axis2/trunk/c/util/src/array_list.c (original)
+++ webservices/axis2/trunk/c/util/src/array_list.c Sat Dec  2 08:38:17 2006
@@ -16,6 +16,7 @@
 
 #include <axis2_array_list.h>
 #include <axis2_utils.h>
+#include <string.h>
 
 typedef struct axis2_array_list_impl
 {
@@ -177,12 +178,19 @@
     {
         int new_capacity = (array_list_impl->capacity * 2 > min_capacity) ?
                 (array_list_impl->capacity * 2) : min_capacity;
-        array_list_impl->data = AXIS2_REALLOC(env->allocator, array_list_impl->data, sizeof(void*) * new_capacity);
-        if (!array_list_impl->data)
+        void **data = (void**) AXIS2_MALLOC(env->allocator,
+                                            sizeof(void*) * new_capacity);
+        if (!data)
         {
             AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
             return AXIS2_FAILURE;
         }
+        memcpy(data, array_list_impl->data,
+               sizeof(void*) * array_list_impl->capacity);
+               
+        AXIS2_FREE(env->allocator, array_list_impl->data);
+
+        array_list_impl->data = data;
         array_list_impl->capacity = new_capacity;
     }
     return AXIS2_SUCCESS;

Modified: webservices/axis2/trunk/c/util/src/dir_handler.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/util/src/dir_handler.c?view=diff&rev=481577&r1=481576&r2=481577
==============================================================================
--- webservices/axis2/trunk/c/util/src/dir_handler.c (original)
+++ webservices/axis2/trunk/c/util/src/dir_handler.c Sat Dec  2 08:38:17 2006
@@ -346,9 +346,9 @@
 #ifndef WIN32
     for (i = 0; i < count; i++)
     {
-        free(files[i]);
+        AXIS2_FREE(env->allocator, files[i]);
     }
-    free(files);
+    AXIS2_FREE(env->allocator, files);
 #endif
     return file_list;
 }

Modified: webservices/axis2/trunk/c/util/src/env.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/util/src/env.c?view=diff&rev=481577&r1=481576&r2=481577
==============================================================================
--- webservices/axis2/trunk/c/util/src/env.c (original)
+++ webservices/axis2/trunk/c/util/src/env.c Sat Dec  2 08:38:17 2006
@@ -240,6 +240,6 @@
         AXIS2_THREAD_POOL_FREE(env->thread_pool);
     }
     if (env)
-        free(env);
+        AXIS2_FREE(env->allocator, env);
     return AXIS2_SUCCESS;
 }

Modified: webservices/axis2/trunk/c/util/src/error.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/util/src/error.c?view=diff&rev=481577&r1=481576&r2=481577
==============================================================================
--- webservices/axis2/trunk/c/util/src/error.c (original)
+++ webservices/axis2/trunk/c/util/src/error.c Sat Dec  2 08:38:17 2006
@@ -466,6 +466,20 @@
     axis2_error_messages[AXIS2_ERROR_WSDL_SCHEMA_IS_NULL] =
         "Schema is NULL";
 
+    /* repos */
+    axis2_error_messages[AXIS2_ERROR_REPOS_NOT_AUTHENTICATED] =
+        "NOT_AUTHENTICATED";
+    axis2_error_messages[AXIS2_ERROR_REPOS_UNSUPPORTED_MODE] =
+        "UNSUPPORTED_MODE";
+    axis2_error_messages[AXIS2_ERROR_REPOS_EXPIRED] =
+        "EXPIRED";
+    axis2_error_messages[AXIS2_ERROR_REPOS_NOT_IMPLEMENTED] =
+        "NOT_IMPLEMENTED";
+    axis2_error_messages[AXIS2_ERROR_REPOS_NOT_FOUND] =
+        "NOT_FOUND";
+    axis2_error_messages[AXIS2_ERROR_REPOS_BAD_SEARCH_TEXT] =
+        "BAD_SEARCH_TEXT";
+
     return AXIS2_SUCCESS;
 }
 
@@ -474,11 +488,11 @@
 {
     if (error && NULL != error->ops)
     {
-        free(error->ops);
+        AXIS2_FREE(error->allocator, error->ops);
     }
     if (error)
     {
-        free(error);
+        AXIS2_FREE(error->allocator, error);
     }
     return AXIS2_SUCCESS;
 }
@@ -495,6 +509,8 @@
 
     if (!error)
         return NULL;
+
+    error->allocator = allocator;
 
     error->ops =
         (axis2_error_ops_t *) AXIS2_MALLOC(allocator,

Modified: webservices/axis2/trunk/c/util/src/properties.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/util/src/properties.c?view=diff&rev=481577&r1=481576&r2=481577
==============================================================================
--- webservices/axis2/trunk/c/util/src/properties.c (original)
+++ webservices/axis2/trunk/c/util/src/properties.c Sat Dec  2 08:38:17 2006
@@ -360,17 +360,21 @@
     return start;
 }
 
+#define MAX_SIZE 1024
+#define MAX_ALLOC (MAX_SIZE * 64)
+
 axis2_char_t*
 axis2_properties_read(FILE* input,
         const axis2_env_t* env)
 {
-    const int MAX_SIZE = 1000;
     int nread = 0;
     axis2_char_t* out_stream = NULL;
     int ncount = 0;
+    size_t curr_alloc = MAX_SIZE * 2;
+    size_t total_alloc = curr_alloc;
 
     out_stream = (axis2_char_t*) AXIS2_MALLOC(env-> allocator,
-            sizeof(axis2_char_t) * MAX_SIZE);
+            sizeof(axis2_char_t) * curr_alloc);
     if (out_stream == NULL)
     {
         return NULL;
@@ -378,13 +382,27 @@
 
     do
     {
-        nread = fread(out_stream + ncount, sizeof(axis2_char_t), MAX_SIZE, input);
+        nread = fread(out_stream + ncount, sizeof(axis2_char_t), MAX_SIZE,
+                      input);
         ncount += nread;
-        out_stream = (axis2_char_t*) AXIS2_REALLOC(env-> allocator, out_stream,
-                sizeof(axis2_char_t) * (MAX_SIZE + ncount));
-        if (out_stream == NULL)
+
+        if (ncount + MAX_SIZE > total_alloc)
         {
-            return NULL;
+            if (curr_alloc < MAX_ALLOC)
+            {
+                curr_alloc *= 2;
+            }
+
+            total_alloc += curr_alloc;
+            axis2_char_t *new_stream = AXIS2_MALLOC(env->allocator,
+                                           sizeof(axis2_char_t) * total_alloc);
+            if (new_stream == NULL)
+            {
+                return NULL;
+            }
+
+            memcpy(new_stream, out_stream, sizeof(axis2_char_t) * ncount);
+            out_stream = new_stream;
         }
     }
     while (nread == MAX_SIZE);



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org