Author: brane
Date: Wed Feb  4 09:17:01 2015
New Revision: 1657031

URL: http://svn.apache.org/r1657031
Log:
On the reuse-ra-session branch: Introduce explicit session reuse and closing.

* BRANCH-README: Update status.

* subversion/include/private/svn_ra_private.h
  (svn_ra__close): New; closes an RA session.
* subversion/libsvn_ra/ra_loader.c
  (svn_ra__close): Implement.

* subversion/libsvn_client/ra_cache.c: Imclude svn_ra_private.h.
  (RA_CACHE_DBG): Renamed from RCTX_DBG; all uses updated.
  (close_ra_session): Renamed from release_session; all uses updated.
   Remove the session from the cache and close it.
  (svn_client__ra_cache_init): Register cleanup_ra_cache as a
   pre-cleanup handler so that it interacts properly with close_ra_session.
  (svn_client__ra_cache_release_session): Release the session to
   the RA cache freelist and prevent close_ra_session from running.

Modified:
    subversion/branches/reuse-ra-session/BRANCH-README
    
subversion/branches/reuse-ra-session/subversion/include/private/svn_ra_private.h
    subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.c
    subversion/branches/reuse-ra-session/subversion/libsvn_ra/ra_loader.c

Modified: subversion/branches/reuse-ra-session/BRANCH-README
URL: 
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/BRANCH-README?rev=1657031&r1=1657030&r2=1657031&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/BRANCH-README (original)
+++ subversion/branches/reuse-ra-session/BRANCH-README Wed Feb  4 09:17:01 2015
@@ -12,15 +12,16 @@ STATUS
 done:
 - Initial implementation.
 - Separate active and inactive session lists.
+- Introduce explicit session reuse and closing.
 
 todo:
-- Fix timeout in davautocheck tests at log_tests.py::log_diff_moved.
-- Limit the number of unused open sessions.
+- Add explicit session reuse throughout libsvn_client.
+- Add new RA method (svn_ra__ping?) to verify that a session
+  about to be reused is valid.
+- Limit the number of idle open sessions in the cache.
 - Run performance comparisons between trunk and branch to prove that
   the RA session cache does in fact speed things up.
-- Add new RA capability to signal if RA session is stateless and reusable.
 - Implement svn_client_close_all_sessions().
-- Switch code to use new functions.
 
 PROBLEM
 =======

Modified: 
subversion/branches/reuse-ra-session/subversion/include/private/svn_ra_private.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/include/private/svn_ra_private.h?rev=1657031&r1=1657030&r2=1657031&view=diff
==============================================================================
--- 
subversion/branches/reuse-ra-session/subversion/include/private/svn_ra_private.h
 (original)
+++ 
subversion/branches/reuse-ra-session/subversion/include/private/svn_ra_private.h
 Wed Feb  4 09:17:01 2015
@@ -39,6 +39,17 @@
 extern "C" {
 #endif /* __cplusplus */
 
+/**
+ * Close the conneection managed by @a session and destroy the
+ * session. When this function returns, the @a session pointer
+ * is no longer valid.
+ *
+ * @since New in 1.9.
+ */
+void
+svn_ra__close(svn_ra_session_t *session);
+
+
 /* Equivalent to svn_ra__assert_capable_server()
    for SVN_RA_CAPABILITY_MERGEINFO. */
 svn_error_t *

Modified: 
subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.c?rev=1657031&r1=1657030&r2=1657031&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.c 
(original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.c 
Wed Feb  4 09:17:01 2015
@@ -25,15 +25,16 @@
 #include <apr_pools.h>
 
 #include "svn_dirent_uri.h"
+#include "private/svn_ra_private.h"
 #include "svn_private_config.h"
 
 #include "ra_cache.h"
 #include "private/svn_debug.h"
 
 #if 0
-#define RCTX_DBG(x) SVN_DBG(x)
+#define RA_CACHE_DBG(x) SVN_DBG(x)
 #else
-#define RCTX_DBG(x)
+#define RA_CACHE_DBG(x)
 #endif
 
 typedef struct svn_client__ra_session_t
@@ -73,32 +74,34 @@ typedef struct svn_client__ra_session_t
 
 
 static apr_status_t
-release_session(void *data)
+close_ra_session(void *data)
 {
   svn_client__ra_session_t *cache_entry = data;
   svn_client__ra_cache_t *ra_cache = cache_entry->ra_cache;
 
-  /* Remove the session from the active table and insert it into the
-     inactive list. */
   if (ra_cache)
     {
-#ifdef SVN_DEBUG
-      /* Double-check that this entry is not part of the freelist. */
-      assert(cache_entry == APR_RING_NEXT(cache_entry, freelist));
-      assert(cache_entry == APR_RING_PREV(cache_entry, freelist));
-#endif /* SVN_DEBUG */
+      svn_ra_session_t *const session = cache_entry->session;
 
+      /* Remove the session from the active table and/or the inactive list. */
       apr_hash_set(ra_cache->active, &cache_entry->session,
                    sizeof(cache_entry->session), NULL);
-      APR_RING_INSERT_HEAD(&ra_cache->freelist, cache_entry,
-                           svn_client__ra_session_t, freelist);
-    }
+      APR_RING_REMOVE(cache_entry, freelist);
+      APR_RING_ELEM_INIT(cache_entry, freelist);
 
-  cache_entry->owner_pool = NULL;
-  cache_entry->cb_table = NULL;
-  cache_entry->cb_baton = NULL;
+      /* Close and invalidate the session. */
+      cache_entry->session = NULL;
+      svn_ra__close(session);
 
-  RCTX_DBG(("SESSION(%d): Released\n", cache_entry->id));
+      RA_CACHE_DBG(("SESSION(%d): Closed\n", cache_entry->id));
+    }
+  else
+    {
+      /* The cache is being destroyed; don't do anything, since the
+         sessions will have already been closed in the session pool
+         cleanup handlers by the time we get here. */
+      RA_CACHE_DBG(("SESSION(%d): Cleanup\n", cache_entry->id));
+    }
 
   return APR_SUCCESS;
 }
@@ -120,9 +123,9 @@ cleanup_ra_cache(void *data)
 
   APR_RING_FOREACH(cache_entry, &ra_cache->freelist,
                    svn_client__ra_session_t, freelist)
-    cache_entry->ra_cache = NULL;
+      cache_entry->ra_cache = NULL;
 
-  RCTX_DBG(("RA_CACHE: Cleanup\n"));
+  RA_CACHE_DBG(("RA_CACHE: Cleanup\n"));
 
   return APR_SUCCESS;
 }
@@ -132,7 +135,7 @@ svn_client__ra_cache_init(svn_client__pr
                           apr_hash_t *config,
                           apr_pool_t *pool)
 {
-  RCTX_DBG(("RA_CACHE: Init\n"));
+  RA_CACHE_DBG(("RA_CACHE: Init\n"));
 
   private_ctx->ra_cache.pool = pool;
   private_ctx->ra_cache.config = config;
@@ -140,11 +143,11 @@ svn_client__ra_cache_init(svn_client__pr
   APR_RING_INIT(&private_ctx->ra_cache.freelist,
                 svn_client__ra_session_t, freelist);
 
-  /* This cleanup must always be registered last (i.e., after the hash
-     table of active sessions is created), so that all the bits of the
-     cache remain valid when it is run. */
-  apr_pool_cleanup_register(pool, &private_ctx->ra_cache, cleanup_ra_cache,
-                            apr_pool_cleanup_null);
+  /* This cleanup must be registered to run before the subpools (which
+     include pools of cached sessions) are destroyed, so that the
+     close_ra_session handler behaves correctly. */
+  apr_pool_pre_cleanup_register(pool, &private_ctx->ra_cache,
+                                cleanup_ra_cache);
 }
 
 static svn_error_t *
@@ -402,7 +405,7 @@ svn_client__ra_cache_open_session(svn_ra
       APR_RING_REMOVE(cache_entry, freelist);
       APR_RING_ELEM_INIT(cache_entry, freelist);
 
-      RCTX_DBG(("SESSION(%d): Reused\n", cache_entry->id));
+      RA_CACHE_DBG(("SESSION(%d): Reused\n", cache_entry->id));
     }
   else
     {
@@ -446,7 +449,7 @@ svn_client__ra_cache_open_session(svn_ra
       SVN_ERR(svn_ra_get_repos_root2(session, &cache_entry->root_url,
                                      ra_cache->pool));
 
-      RCTX_DBG(("SESSION(%d): Open('%s')\n", cache_entry->id, base_url));
+      RA_CACHE_DBG(("SESSION(%d): Open('%s')\n", cache_entry->id, base_url));
 
       apr_hash_set(ra_cache->active, &cache_entry->session,
                    sizeof(cache_entry->session), cache_entry);
@@ -458,7 +461,7 @@ svn_client__ra_cache_open_session(svn_ra
   cache_entry->cb_table = cbtable;
   cache_entry->cb_baton = callback_baton;
   cache_entry->progress = 0;
-  apr_pool_cleanup_register(result_pool, cache_entry, release_session,
+  apr_pool_cleanup_register(result_pool, cache_entry, close_ra_session,
                             apr_pool_cleanup_null);
 
   *session_p = cache_entry->session;
@@ -478,6 +481,28 @@ svn_client__ra_cache_release_session(svn
   SVN_ERR_ASSERT_NO_RETURN(cache_entry->session == session);
   SVN_ERR_ASSERT_NO_RETURN(cache_entry->owner_pool != NULL);
 
-  apr_pool_cleanup_run(cache_entry->owner_pool, cache_entry,
-                       release_session);
+  /* Prevent the registered cleanup for this session from running,
+     since we're releasing, not closing, the session. */
+  apr_pool_cleanup_kill(cache_entry->owner_pool,
+                        cache_entry, close_ra_session);
+
+  /* Remove the session from the active table and insert it into
+     the inactive list. */
+  apr_hash_set(ra_cache->active, &cache_entry->session,
+               sizeof(cache_entry->session), NULL);
+
+#ifdef SVN_DEBUG
+  /* Double-check that this entry is not part of the freelist. */
+  assert(cache_entry == APR_RING_NEXT(cache_entry, freelist));
+  assert(cache_entry == APR_RING_PREV(cache_entry, freelist));
+#endif /* SVN_DEBUG */
+
+  APR_RING_INSERT_HEAD(&ra_cache->freelist, cache_entry,
+                       svn_client__ra_session_t, freelist);
+
+  cache_entry->owner_pool = NULL;
+  cache_entry->cb_table = NULL;
+  cache_entry->cb_baton = NULL;
+
+  RA_CACHE_DBG(("SESSION(%d): Released\n", cache_entry->id));
 }

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra/ra_loader.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra/ra_loader.c?rev=1657031&r1=1657030&r2=1657031&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_ra/ra_loader.c 
(original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_ra/ra_loader.c Wed 
Feb  4 09:17:01 2015
@@ -225,6 +225,16 @@ check_ra_version(const svn_version_t *ra
   return SVN_NO_ERROR;
 }
 
+void
+svn_ra__close(svn_ra_session_t *session)
+{
+  /* Just clear the pool here. Do not destroy it, because we don't own
+     it and we don't know how many references there may be to this
+     pool elsewhere. */
+  if (session && session->pool)
+    apr_pool_clear(session->pool);
+}
+
 /* -------------------------------------------------------------- */
 
 /*** Public Interfaces ***/


Reply via email to