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 ***/