Author: stefan2
Date: Wed Mar 26 16:44:46 2014
New Revision: 1581923

URL: http://svn.apache.org/r1581923
Log:
Simplify svnserve object pool usage:  Since we can't reuse open
repository instances ATM, drop the repository pool.  Instead make
the repository an object with connection lifetime (still created
lazily).

* subversion/svnserve/server.h
  (serve_params_t): Replace repos pool with the config hash that
                    we will need to open any repos directly.

* subversion/svnserve/svnserve.c
  (sub_main): FS_CONFIG is now part of the PARAMS struct and we
              don't have a REPOS_POOL anymore.

* subversion/svnserve/serve.c
  (reset_repos): We don't temporarily release repositories anymore,
                 thus we can drop this pool cleanup callback.
  (find_repos): Replace the REPOS_POOL with a FS_CONFIG hash such
                that we may call svn_repos_open2() directly.  Also,
                all return objects have the same lifetime now, hence
                only one pool is required.
  (construct_server_baton): Update caller. Be sure to give repository-
                            related objects the same lifetime as the
                            connection.
  (reopen_repos): No longer used.
  (serve_interruptable): No re-initialization of connections required
                         anymore.

Modified:
    subversion/trunk/subversion/svnserve/serve.c
    subversion/trunk/subversion/svnserve/server.h
    subversion/trunk/subversion/svnserve/svnserve.c

Modified: subversion/trunk/subversion/svnserve/serve.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svnserve/serve.c?rev=1581923&r1=1581922&r2=1581923&view=diff
==============================================================================
--- subversion/trunk/subversion/svnserve/serve.c (original)
+++ subversion/trunk/subversion/svnserve/serve.c Wed Mar 26 16:44:46 2014
@@ -3374,26 +3374,13 @@ repos_path_valid(const char *path)
   return TRUE;
 }
 
-/* APR pool cleanup callback that resets the REPOS pointer in ARG. */
-static apr_status_t
-reset_repos(void *arg)
-{
-  repository_t *repository = arg;
-  repository->repos = NULL;
-
-  return APR_SUCCESS;
-}
-
 /* Look for the repository given by URL, using ROOT as the virtual
  * repository root.  If we find one, fill in the repos, fs, repos_url,
- * and fs_path fields of REPOSITORY.  REPOSITORY->REPO will be allocated
- * SCRATCH_POOL because repositories may be closed and re-opened during
- * the lifetime of a connection.   All other parts in REPOSITORY must
- * be allocated in RESULT_POOL.  VHOST and READ_ONLY flags are the same
- * as in the server baton.
+ * and fs_path fields of REPOSITORY.  VHOST and READ_ONLY flags are the
+ * same as in the server baton.
  *
- * CONFIG_POOL, AUTHZ_POOL and REPOS_POOL shall be used to load any
- * object of the respective type.
+ * CONFIG_POOL and AUTHZ_POOL shall be used to load any object of the
+ * respective type.
  */
 static svn_error_t *
 find_repos(const char *url,
@@ -3404,9 +3391,8 @@ find_repos(const char *url,
            repository_t *repository,
            svn_repos__config_pool_t *config_pool,
            svn_repos__authz_pool_t *authz_pool,
-           svn_repos__repos_pool_t *repos_pool,
-           apr_pool_t *result_pool,
-           apr_pool_t *scratch_pool)
+           apr_hash_t *fs_config,
+           apr_pool_t *pool)
 {
   const char *path, *full_path, *fs_path, *hooks_env;
   svn_stringbuf_t *url_buf;
@@ -3423,8 +3409,8 @@ find_repos(const char *url,
       if (path == NULL)
         path = "";
     }
-  path = svn_relpath_canonicalize(path, result_pool);
-  path = svn_path_uri_decode(path, result_pool);
+  path = svn_relpath_canonicalize(path, pool);
+  path = svn_path_uri_decode(path, pool);
 
   /* Ensure that it isn't possible to escape the root by disallowing
      '..' segments. */
@@ -3433,61 +3419,55 @@ find_repos(const char *url,
                             "Couldn't determine repository path");
 
   /* Join the server-configured root with the client path. */
-  full_path = svn_dirent_join(svn_dirent_canonicalize(root, result_pool),
-                              path, result_pool);
+  full_path = svn_dirent_join(svn_dirent_canonicalize(root, pool),
+                              path, pool);
 
   /* Search for a repository in the full path. */
-  repository->repos_root = svn_repos_find_root_path(full_path, result_pool);
+  repository->repos_root = svn_repos_find_root_path(full_path, pool);
   if (!repository->repos_root)
     return svn_error_createf(SVN_ERR_RA_SVN_REPOS_NOT_FOUND, NULL,
                              "No repository found in '%s'", url);
 
   /* Open the repository and fill in b with the resulting information. */
-  SVN_ERR(svn_repos__repos_pool_get(&repository->repos, repos_pool,
-                                    repository->repos_root, "",
-                                    scratch_pool));
+  SVN_ERR(svn_repos_open2(&repository->repos, repository->repos_root,
+                          fs_config, pool));
   SVN_ERR(svn_repos_remember_client_capabilities(repository->repos,
                                                  repository->capabilities));
   repository->fs = svn_repos_fs(repository->repos);
   fs_path = full_path + strlen(repository->repos_root);
   repository->fs_path = svn_stringbuf_create(*fs_path ? fs_path : "/",
-                                             result_pool);
-  url_buf = svn_stringbuf_create(url, result_pool);
+                                             pool);
+  url_buf = svn_stringbuf_create(url, pool);
   svn_path_remove_components(url_buf,
                         svn_path_component_count(repository->fs_path->data));
   repository->repos_url = url_buf->data;
   repository->authz_repos_name = svn_dirent_is_child(root,
                                                      repository->repos_root,
-                                                     result_pool);
+                                                     pool);
   if (repository->authz_repos_name == NULL)
     repository->repos_name = svn_dirent_basename(repository->repos_root,
-                                                 result_pool);
+                                                 pool);
   else
     repository->repos_name = repository->authz_repos_name;
   repository->repos_name = svn_path_uri_encode(repository->repos_name,
-                                               result_pool);
-
-  /* Reset the REPOS pointer as soon as the REPOS will be returned to the
-     REPOS_POOL. */
-  apr_pool_cleanup_register(scratch_pool, repository, reset_repos,
-                            apr_pool_cleanup_null);
+                                               pool);
 
   /* If the svnserve configuration has not been loaded then load it from the
    * repository. */
   if (NULL == cfg)
     {
-      repository->base = svn_repos_conf_dir(repository->repos, result_pool);
+      repository->base = svn_repos_conf_dir(repository->repos, pool);
 
       SVN_ERR(svn_repos__config_pool_get(&cfg, NULL, config_pool,
                                          svn_repos_svnserve_conf
-                                            (repository->repos, result_pool), 
+                                            (repository->repos, pool),
                                          FALSE, FALSE, repository->repos,
-                                         result_pool));
+                                         pool));
     }
 
-  SVN_ERR(load_pwdb_config(repository, cfg, config_pool, result_pool));
+  SVN_ERR(load_pwdb_config(repository, cfg, config_pool, pool));
   SVN_ERR(load_authz_config(repository, repository->repos_root, cfg,
-                            authz_pool, result_pool));
+                            authz_pool, pool));
 
 #ifdef SVN_HAVE_SASL
     {
@@ -3509,10 +3489,10 @@ find_repos(const char *url,
 #endif
 
   /* Use the repository UUID as the default realm. */
-  SVN_ERR(svn_fs_get_uuid(repository->fs, &repository->realm, result_pool));
+  SVN_ERR(svn_fs_get_uuid(repository->fs, &repository->realm, pool));
   svn_config_get(cfg, &repository->realm, SVN_CONFIG_SECTION_GENERAL,
                  SVN_CONFIG_OPTION_REALM, repository->realm);
-  repository->realm = apr_pstrdup(result_pool, repository->realm);
+  repository->realm = apr_pstrdup(pool, repository->realm);
 
   /* Make sure it's possible for the client to authenticate.  Note
      that this doesn't take into account any authz configuration read
@@ -3524,9 +3504,9 @@ find_repos(const char *url,
   svn_config_get(cfg, &hooks_env, SVN_CONFIG_SECTION_GENERAL,
                  SVN_CONFIG_OPTION_HOOKS_ENV, NULL);
   if (hooks_env)
-    hooks_env = svn_dirent_internal_style(hooks_env, scratch_pool);
+    hooks_env = svn_dirent_internal_style(hooks_env, pool);
 
-  repository->hooks_env = apr_pstrdup(result_pool, hooks_env);
+  repository->hooks_env = apr_pstrdup(pool, hooks_env);
 
   return SVN_NO_ERROR;
 }
@@ -3815,8 +3795,8 @@ construct_server_baton(server_baton_t **
   err = handle_config_error(find_repos(client_url, params->root, b->vhost,
                                        b->read_only, params->cfg,
                                        b->repository, params->config_pool,
-                                       params->authz_pool, params->repos_pool, 
-                                       conn_pool, scratch_pool),
+                                       params->authz_pool, params->fs_config, 
+                                       conn_pool),
                             b);
   if (!err)
     {
@@ -3886,7 +3866,7 @@ construct_server_baton(server_baton_t **
                                           scratch_pool),
                       ra_client_string, client_string));
 
-  warn_baton = apr_pcalloc(scratch_pool, sizeof(*warn_baton));
+  warn_baton = apr_pcalloc(conn_pool, sizeof(*warn_baton));
   warn_baton->server = b;
   warn_baton->conn = conn;
   svn_fs_set_warning_func(b->repository->fs, fs_warning_func, warn_baton);
@@ -3909,45 +3889,6 @@ construct_server_baton(server_baton_t **
   return SVN_NO_ERROR;
 }
 
-/* Open a svn_repos object in CONNECTION for the same repository and with
-   the same settings as last time.  The repository object remains valid
-   until POOL gets cleaned up at which point the respective pointer in
-   CONNECTION reset.  The repository in CONNECTION must have been opened
-   at some point in the past using construct_server_baton.
- */
-static svn_error_t *
-reopen_repos(connection_t *connection,
-             apr_pool_t *pool)
-{
-  fs_warning_baton_t *warn_baton = apr_pcalloc(pool, sizeof(*warn_baton));
-  repository_t *repository = connection->baton->repository;
-
-  /* Open the repository and fill in b with the resulting information. */
-  SVN_ERR(svn_repos__repos_pool_get(&repository->repos,
-                                    connection->params->repos_pool,
-                                    repository->repos_root, repository->uuid,
-                                    pool));
-  repository->fs = svn_repos_fs(repository->repos);
-
-  /* Reset the REPOS pointer as soon as the REPOS will be returned to the
-     REPOS_POOL. */
-  apr_pool_cleanup_register(pool, repository, reset_repos,
-                            apr_pool_cleanup_null);
-
-  /* Configure svn_repos object */
-  SVN_ERR(svn_repos_remember_client_capabilities(repository->repos,
-                                                 repository->capabilities));
-  SVN_ERR(svn_repos_hooks_setenv(repository->repos, repository->hooks_env,
-                                 pool));
-  
-  warn_baton->server = connection->baton;
-  warn_baton->conn = connection->conn;
-  svn_fs_set_warning_func(connection->baton->repository->fs,
-                          fs_warning_func, &warn_baton);
-
-  return SVN_NO_ERROR;
-}
-
 svn_error_t *
 serve_interruptable(svn_boolean_t *terminate_p,
                     connection_t *connection,
@@ -3964,14 +3905,8 @@ serve_interruptable(svn_boolean_t *termi
   for (command = main_commands; command->cmdname; command++)
     svn_hash_sets(cmd_hash, command->cmdname, command);
 
-  /* Auto-initialize connection & open repository */
-  if (connection->conn)
-    {
-      /* This is not the first call for CONNECTION. */
-      if (connection->baton->repository->repos == NULL)
-        err = reopen_repos(connection, pool);
-    }
-  else
+  /* Auto-initialize connection */
+  if (! connection->conn)
     {
       apr_status_t ar;
 

Modified: subversion/trunk/subversion/svnserve/server.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svnserve/server.h?rev=1581923&r1=1581922&r2=1581923&view=diff
==============================================================================
--- subversion/trunk/subversion/svnserve/server.h (original)
+++ subversion/trunk/subversion/svnserve/server.h Wed Mar 26 16:44:46 2014
@@ -128,8 +128,9 @@ typedef struct serve_params_t {
   /* all authz data should be opened through this factory */
   svn_repos__authz_pool_t *authz_pool;
 
-  /* all repositories should be opened through this factory */
-  svn_repos__repos_pool_t *repos_pool;
+  /* The FS configuration to be applied to all repositories.
+     It mainly contains things like cache settings. */
+  apr_hash_t *fs_config;
 
   /* Username case normalization style. */
   enum username_case_type username_case;

Modified: subversion/trunk/subversion/svnserve/svnserve.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svnserve/svnserve.c?rev=1581923&r1=1581922&r2=1581923&view=diff
==============================================================================
--- subversion/trunk/subversion/svnserve/svnserve.c (original)
+++ subversion/trunk/subversion/svnserve/svnserve.c Wed Mar 26 16:44:46 2014
@@ -638,7 +638,6 @@ sub_main(int *exit_code, int argc, const
 #endif
   svn_boolean_t is_multi_threaded;
   enum connection_handling_mode handling_mode = CONNECTION_DEFAULT;
-  apr_hash_t *fs_config = NULL;
   svn_boolean_t cache_fulltexts = TRUE;
   svn_boolean_t cache_txdeltas = TRUE;
   svn_boolean_t cache_revprops = FALSE;
@@ -680,7 +679,7 @@ sub_main(int *exit_code, int argc, const
   params.logger = NULL;
   params.config_pool = NULL;
   params.authz_pool = NULL;
-  params.repos_pool = NULL;
+  params.fs_config = NULL;
   params.vhost = FALSE;
   params.username_case = CASE_ASIS;
   params.memory_cache_size = (apr_uint64_t)-1;
@@ -921,12 +920,12 @@ sub_main(int *exit_code, int argc, const
 
   /* construct object pools */
   is_multi_threaded = handling_mode == connection_mode_thread;
-  fs_config = apr_hash_make(pool);
-  svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_DELTAS,
+  params.fs_config = apr_hash_make(pool);
+  svn_hash_sets(params.fs_config, SVN_FS_CONFIG_FSFS_CACHE_DELTAS,
                 cache_txdeltas ? "1" :"0");
-  svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS,
+  svn_hash_sets(params.fs_config, SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS,
                 cache_fulltexts ? "1" :"0");
-  svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
+  svn_hash_sets(params.fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
                 cache_revprops ? "2" :"0");
 
   SVN_ERR(svn_repos__config_pool_create(&params.config_pool,
@@ -936,10 +935,6 @@ sub_main(int *exit_code, int argc, const
                                        params.config_pool,
                                        is_multi_threaded,
                                        pool));
-  SVN_ERR(svn_repos__repos_pool_create(&params.repos_pool,
-                                       fs_config,
-                                       is_multi_threaded,
-                                       pool));
 
   /* If a configuration file is specified, load it and any referenced
    * password and authorization files. */


Reply via email to