On Fri, May 10, 2013 at 1:16 PM, Philip Martin
<philip.mar...@wandisco.com> wrote:
> Ivan Zhakov <i...@visualsvn.com> writes:
>
>> Another way add some kind of svn__shared_pool_t with atomic reference
>> counter and destroying attached pool when counter reaches zero.
>>
>> Something like this:
>
> An implementation of your idea:
>
> Index: subversion/svnserve/svnserve.c
> ===================================================================
> --- subversion/svnserve/svnserve.c      (revision 1480899)
> +++ subversion/svnserve/svnserve.c      (working copy)
> @@ -53,6 +53,7 @@
>
>  #include "private/svn_dep_compat.h"
>  #include "private/svn_cmdline_private.h"
> +#include "private/svn_atomic.h"
>
>  #include "winservice.h"
>
> @@ -378,11 +379,44 @@ static apr_status_t redirect_stdout(void *arg)
>    return apr_file_dup2(out_file, err_file, pool);
>  }
>
> +#if APR_HAS_THREADS
> +/* The pool passed to apr_thread_create can only be released when both
> +
> +      A: the call to apr_thread_create has returned to the calling thread
> +      B: the new thread has started running and reached apr_thread_start_t
> +
> +   So we set the atomic counter to 2 then both the calling thread and
> +   the new thread decrease it and when it reaches 0 the pool can be
> +   released.  */
> +struct shared_pool_t {
> +  svn_atomic_t count;
> +  apr_pool_t *pool;
> +};
> +
> +static struct shared_pool_t *
> +attach_shared_pool(apr_pool_t *pool)
> +{
> +  struct shared_pool_t *shared = apr_palloc(pool, sizeof(struct 
> shared_pool_t));
> +
> +  shared->pool = pool;
> +  svn_atomic_set(&shared->count, 2);
> +
> +  return shared;
> +}
> +
> +static void
> +release_shared_pool(struct shared_pool_t *shared)
> +{
> +  if (svn_atomic_dec(&shared->count) == 0)
> +    svn_pool_destroy(shared->pool);
> +}
> +#endif
> +
>  /* "Arguments" passed from the main thread to the connection thread */
>  struct serve_thread_t {
>    svn_ra_svn_conn_t *conn;
>    serve_params_t *params;
> -  apr_pool_t *pool;
> +  struct shared_pool_t *shared_pool;
>  };
>
>  #if APR_HAS_THREADS
> @@ -390,8 +424,8 @@ static void * APR_THREAD_FUNC serve_thread(apr_thr
>  {
>    struct serve_thread_t *d = data;
>
> -  svn_error_clear(serve(d->conn, d->params, d->pool));
> -  svn_pool_destroy(d->pool);
> +  svn_error_clear(serve(d->conn, d->params, d->shared_pool->pool));
> +  release_shared_pool(d->shared_pool);
>
>    return NULL;
>  }
> @@ -455,6 +489,7 @@ int main(int argc, const char *argv[])
>  #if APR_HAS_THREADS
>    apr_threadattr_t *tattr;
>    apr_thread_t *tid;
> +  struct shared_pool_t *shared_pool;
>
>    struct serve_thread_t *thread_data;
>  #endif
> @@ -1093,6 +1128,7 @@ int main(int argc, const char *argv[])
>               particularly sophisticated strategy for a threaded server, it's
>               little different from forking one process per connection. */
>  #if APR_HAS_THREADS
> +          shared_pool = attach_shared_pool(connection_pool);
>            status = apr_threadattr_create(&tattr, connection_pool);
>            if (status)
>              {
> @@ -1112,9 +1148,9 @@ int main(int argc, const char *argv[])
>            thread_data = apr_palloc(connection_pool, sizeof(*thread_data));
>            thread_data->conn = conn;
>            thread_data->params = &params;
> -          thread_data->pool = connection_pool;
> +          thread_data->shared_pool = shared_pool;
>            status = apr_thread_create(&tid, tattr, serve_thread, thread_data,
> -                                     connection_pool);
> +                                     shared_pool->pool);
>            if (status)
>              {
>                err = svn_error_wrap_apr(status, _("Can't create thread"));
> @@ -1122,6 +1158,7 @@ int main(int argc, const char *argv[])
>                svn_error_clear(err);
>                exit(1);
>              }
> +          release_shared_pool(shared_pool);
>  #endif
>            break;
>
>
Looks good!

My original idea was to make svn__shared_pool library private API for
better encapsulation, but we can do this anytime later. I'll vote for
backport on Monday.

-- 
Ivan Zhakov
CTO | VisualSVN | http://www.visualsvn.com

Reply via email to