You are viewing a plain text version of this content. The canonical link for it is here.
Posted to site-cvs@tcl.apache.org by mx...@apache.org on 2016/02/05 11:49:00 UTC

svn commit: r1728632 - in /tcl/rivet/trunk: ChangeLog src/mod_rivet/rivet_worker_mpm.c

Author: mxmanghi
Date: Fri Feb  5 10:49:00 2016
New Revision: 1728632

URL: http://svn.apache.org/viewvc?rev=1728632&view=rev
Log:
    * src/mod_rivet/rivet_worker_mpm.c: removed code implmenting the old
    model of inter thread communication. This should fix the problem of
    redundant mutex/cond variable creation/destruction needed by the former
    model to avoid memory leaks


Modified:
    tcl/rivet/trunk/ChangeLog
    tcl/rivet/trunk/src/mod_rivet/rivet_worker_mpm.c

Modified: tcl/rivet/trunk/ChangeLog
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/ChangeLog?rev=1728632&r1=1728631&r2=1728632&view=diff
==============================================================================
--- tcl/rivet/trunk/ChangeLog (original)
+++ tcl/rivet/trunk/ChangeLog Fri Feb  5 10:49:00 2016
@@ -1,3 +1,9 @@
+2016-02-05 Massimo Manghi <mx...@apache.org>
+    * src/mod_rivet/rivet_worker_mpm.c: removed code implmenting the old
+    model of inter thread communication. This should fix the problem of
+    redundant mutex/cond variable creation/destruction needed by the former
+    model to avoid memory leaks
+
 2016-02-01 Massimo Manghi <mx...@apache.org>
     * src/mod_rivet/rivet_worker_mpm.c: upon process shutdown thread status 
     has to be set to 'init' to force thread exit

Modified: tcl/rivet/trunk/src/mod_rivet/rivet_worker_mpm.c
URL: http://svn.apache.org/viewvc/tcl/rivet/trunk/src/mod_rivet/rivet_worker_mpm.c?rev=1728632&r1=1728631&r2=1728632&view=diff
==============================================================================
--- tcl/rivet/trunk/src/mod_rivet/rivet_worker_mpm.c (original)
+++ tcl/rivet/trunk/src/mod_rivet/rivet_worker_mpm.c Fri Feb  5 10:49:00 2016
@@ -49,8 +49,6 @@
     #define HTTP_REQUESTS_PROC(request_proc_call) request_proc_call;
 #endif
 
-#define THREAD_MODEL_NG 1
-
 extern mod_rivet_globals* module_globals;
 extern apr_threadkey_t*   rivet_thread_key;
 
@@ -79,16 +77,6 @@ typedef struct mpm_bridge_status {
 } mpm_bridge_status;
 
 
-#ifndef THREAD_MODEL_NG
-/* Job types a worker thread is supposed to respond to */
-
-typedef int rivet_job_t;
-enum {
-    request,
-    orderly_exit
-};
-#endif
-
 /* 
  * data structure to work as communication
  * between Tcl worker thread and HTTP request handler 
@@ -96,9 +84,6 @@ enum {
 
 typedef struct _handler_private 
 {
-#ifndef THREAD_MODEL_NG
-    rivet_job_t             job_type;
-#endif
     apr_thread_cond_t*      cond;
     apr_thread_mutex_t*     mutex;
     request_rec*            r;              /* request rec                 */
@@ -117,9 +102,6 @@ enum
     child_exit
 };
 
-
-#ifdef THREAD_MODEL_NG
-
 /* 
  * -- Worker_Bridge_Shutdown
  *
@@ -172,86 +154,10 @@ void Worker_Bridge_Shutdown (void)
     return;
 }
 
-#else
-
-/* 
- * -- Worker_Bridge_Shutdown
- *
- *  Child process shutdown. The thread count is read and 
- * on the job queue are places as many orderly exit commands
- * as the number of existing thread.
- *
- * The procedure exits as soon as the thread count drops to zero
- * or after a 5 seconds wait. If the thread count is not zero when
- * the max wait time elapses an error message is printed in the log
- *
- *  Arguments:
- *
- *      none
- *
- *  Returned value:
- *    
- *      none
- *
- *  Side effects:
- *
- * - The whole pool of worker threads is shut down and either they
- * must be restared or (most likely) the child process can exit.
- *
- */
-
-void Worker_Bridge_Shutdown (void)
-{
-    handler_private* job;
-    int count;
-    int i,waits;
-
-    apr_thread_mutex_lock(module_globals->pool_mutex);
-    job = (handler_private *) apr_pcalloc(module_globals->pool,sizeof(handler_private));
-    apr_thread_mutex_unlock(module_globals->pool_mutex);
-    job->job_type = orderly_exit;
-
-    waits = 5;
-    count = (int) apr_atomic_read32(module_globals->mpm->threads_count);
-    for (i = 0; i < count; i++) { apr_queue_push(module_globals->mpm->queue,job); }
-    apr_sleep(1000000);
-
-    do 
-    {
-        count = (int) apr_atomic_read32(module_globals->mpm->threads_count);
-
-        /* Actually, when Rivet exit command implementation shuts the bridge down
-         * the thread running the command is waiting for the supervisor to terminate
-         * therefore the 'count' variable can't drop to 0
-         */
-
-        if (count <= 1) break;
-
-        ap_log_error(APLOG_MARK, APLOG_ERR, APR_SUCCESS, module_globals->server, 
-                        "Sending %d more stop signals to threads",count);
-        for (i = 0; i < count; i++) { apr_queue_push(module_globals->mpm->queue,job); }
-
-        apr_sleep(500000);
-
-    } while (waits-- > 0);
-
-    count = (int) apr_atomic_read32(module_globals->mpm->threads_count);
-    if (count > 0) 
-    {
-        ap_log_error(APLOG_MARK,APLOG_ERR,APR_EGENERAL,module_globals->server, 
-            "%d threads are still running after 5 attempts. Child process exits anyway",count);
-    }
-    return;
-}
-
-#endif
-
 /*
  * -- request_processor_ng
  */
 
-#ifdef THREAD_MODEL_NG
-
 static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data)
 {
     rivet_thread_private*   private;
@@ -379,132 +285,6 @@ static void* APR_THREAD_FUNC request_pro
     return NULL;
 }
 
-#else
-
-static void* APR_THREAD_FUNC request_processor (apr_thread_t *thd, void *data)
-{
-    rivet_thread_private*   private;
-
-    apr_thread_mutex_lock(module_globals->mpm->job_mutex);
-
-    private = Rivet_CreatePrivateData();
-    private->ext = apr_pcalloc(private->pool,sizeof(mpm_bridge_specific));
-    private->ext->keep_going = 1;
-    private->ext->interps = 
-        apr_pcalloc(private->pool,module_globals->vhosts_count*sizeof(rivet_thread_interp));
-
-    if (private == NULL) 
-    {
-        /* TODO: we have to log something here */
-        apr_thread_exit(thd,APR_SUCCESS);
-        return NULL;
-    }
-    private->channel = Rivet_CreateRivetChannel(private->pool,rivet_thread_key);
-    Rivet_SetupTclPanicProc ();
-    
-    /* So far nothing differs much with what we did for the prefork bridge */
-
-    /* At this stage we have to set up the private interpreters of configured 
-     * virtual hosts (if any). We assume the server_rec stored in the module
-     * globals can be used to retrieve the reference to the root interpreter
-     * configuration and to the rivet global script
-     */
-
-    if (Rivet_VirtualHostsInterps(private) == NULL)
-    {
-        *(apr_thread_t **) apr_array_push(module_globals->mpm->exiting) = thd;
-        apr_thread_cond_signal(module_globals->mpm->job_cond);
-        apr_thread_mutex_unlock(module_globals->mpm->job_mutex);
-        apr_thread_exit(thd,APR_SUCCESS);
-        return NULL;
-    }
-
-    apr_thread_mutex_unlock(module_globals->mpm->job_mutex);       /* unlock job initialization stage */
-
-        /* eventually we increment the number of active threads */
-
-    apr_atomic_inc32(module_globals->mpm->threads_count);
-
-    do
-    {
-        apr_status_t        rv;
-        void*               v;
-        apr_queue_t*        q = module_globals->mpm->queue;
-        handler_private*    request_obj;
-
-        do {
-
-            rv = apr_queue_pop(q, &v);
-
-        } while (rv == APR_EINTR);
-
-        if (rv != APR_SUCCESS) {
-
-            if (rv == APR_EOF) {
-                fprintf(stderr, "request_processor: queue terminated APR_EOF\n");
-                rv = APR_SUCCESS;
-            }
-            else 
-            {
-                fprintf(stderr, "consumer thread exit rv %d\n", rv);
-            }
-            apr_thread_exit(thd, rv);
-            return NULL;
-
-        }
-
-        request_obj = (handler_private *) v;
-        if (request_obj->job_type == orderly_exit)
-        {
-            private->ext->keep_going = 0;
-            continue;
-        }
-
-        /* we proceed with the request processing */
-        
-        apr_atomic_inc32(module_globals->mpm->running_threads_count);
-
-        /* these assignements are crucial for both calling Rivet_SendContent and
-         * for telling the channel where stuff must be sent to */
-
-        private->ctype  = request_obj->ctype;
-
-        HTTP_REQUESTS_PROC(request_obj->code = Rivet_SendContent(private,request_obj->r));
-
-        apr_thread_mutex_lock(request_obj->mutex);
-
-        request_obj->status = done;
-        if (private->thread_exit) request_obj->status = child_exit;
-
-        apr_thread_cond_signal(request_obj->cond);
-        apr_thread_mutex_unlock(request_obj->mutex);
-    
-        private->req_cnt++;
-        apr_atomic_dec32(module_globals->mpm->running_threads_count);
-
-    } while (private->ext->keep_going > 0);
-            
-    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, module_globals->server, "processor thread orderly exit");
-
-    // We don't clean up the thread resources anymore, if the thread exits the whole process terminates
-    // Rivet_ProcessorCleanup(private);
-
-    apr_thread_mutex_lock(module_globals->mpm->job_mutex);
-    *(apr_thread_t **) apr_array_push(module_globals->mpm->exiting) = thd;
-    apr_thread_cond_signal(module_globals->mpm->job_cond);
-    apr_thread_mutex_unlock(module_globals->mpm->job_mutex);
-
-    /* the counter of active threads has to be decremented */
-
-    apr_atomic_dec32(module_globals->mpm->threads_count);
-
-    /* this call triggers thread private stuff clean up by calling processor_cleanup */
-
-    apr_thread_exit(thd,APR_SUCCESS);
-    return NULL;
-}
-
-#endif
 
 static apr_status_t create_worker_thread (apr_thread_t** thd)
 {
@@ -808,8 +588,6 @@ apr_status_t Worker_RequestPrivateCleanu
  *   HTTP status code (see the Apache HTTP web server documentation)
  */
 
-#ifdef THREAD_MODEL_NG
-
 int Worker_MPM_Request (request_rec* r,rivet_req_ctype ctype)
 {
     void*           v;
@@ -866,94 +644,6 @@ int Worker_MPM_Request (request_rec* r,r
     return http_code;
 }
 
-#else
-
-int Worker_MPM_Request (request_rec* r,rivet_req_ctype ctype)
-{
-    handler_private*    request_private;
-    apr_status_t        rv;
-
-    /* We are running within a thread controlled by the framework. On the first request
-       served by this thread we allocate a structure instance of type handler_private 
-       associated to the thread through the 'request_private' thread key */ 
-
-    if (apr_threadkey_private_get ((void **)&request_private,handler_thread_key) != APR_SUCCESS)
-    {
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r, 
-                    MODNAME ": cannot get private data for processor thread");
-
-        return HTTP_INTERNAL_SERVER_ERROR;
-
-    } else if (module_globals->mpm->server_shutdown == 1) {
-
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r, 
-                    MODNAME ": http request aborted during child process shutdown");
-
-        return HTTP_INTERNAL_SERVER_ERROR;
-
-    } else {
-
-        /* if the thread is serving its first request we allocate its private data from the thread pool */
-
-        if (request_private == NULL)
-        {
-            apr_pool_t*     tpool;
-            apr_thread_t*   thread_id;
-            apr_os_thread_t os_thread_id = apr_os_thread_current();
-
-            apr_os_thread_put(&thread_id,&os_thread_id,r->pool);
-
-            tpool = apr_thread_pool_get(thread_id);
-            request_private = apr_pcalloc(tpool,sizeof(handler_private));
-
-            ap_assert(apr_thread_cond_create(&(request_private->cond),tpool) == APR_SUCCESS);
-            ap_assert(apr_thread_mutex_create(&(request_private->mutex),APR_THREAD_MUTEX_UNNESTED,tpool) == APR_SUCCESS);
-            apr_threadkey_private_set (request_private,handler_thread_key);
-
-            apr_pool_cleanup_register(tpool,(void *)request_private,Worker_RequestPrivateCleanup,apr_pool_cleanup_null);
-
-            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r,
-                    MODNAME ": request thread private data allocated");
-
-        }
-
-    }
-
-    /* We prepare the request descriptor object to be placed on the Tcl working threads queue */
-
-    request_private->r          = r;
-    request_private->code       = OK;
-    request_private->status     = init;
-    request_private->job_type   = request;
-    request_private->ctype      = ctype;
-
-    rv = apr_queue_push(module_globals->mpm->queue,request_private);
-    if (rv == APR_SUCCESS)
-    {
-
-        /* After the request has been posted on the thread safe queue we
-         * wait on the condition variable associated to the request_private structure */
-
-        apr_thread_mutex_lock(request_private->mutex);
-        do 
-        {
-            apr_thread_cond_wait(request_private->cond,request_private->mutex);
-        } while (request_private->status == init); 
-        apr_thread_mutex_unlock(request_private->mutex);
-
-    }
-    else
-    {
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,  
-                      MODNAME ": rivet_worker_mpm: could not push request on threads queue");
-        request_private->code = HTTP_INTERNAL_SERVER_ERROR;
-    }
-
-    return request_private->code;
-}
-
-#endif
-
 /* 
  * -- Worker_MPM_Finalize
  *



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