Author: brane
Date: Mon Feb 2 12:34:17 2015
New Revision: 1656451
URL: http://svn.apache.org/r1656451
Log:
On the reuse-ra-session branch: Hide the RA session cache from the public API.
* subversion/include/svn_client.h
(svn_client_ctx_t): Removed the ra_cache member and docstring.
* subversion/libsvn_client/ra_cache.h
(client_ra_cache_t): Moved here from ra_cache.c.
Renamed from svn_client__ra_cache_t.
(client_ctx_t): New. Internal client context.
(CLIENT_CTX_MAGIC): New. Magic identifier for client_ctx_t.
(svn_client__ra_cache_create): Removed.
(svn_client__ra_cache_init): New. Replaces svn_client__ra_cache_create.
(svn_client__ra_cache_open_session,
svn_client__ra_cache_release_session): Update signature and docstring.
* subversion/libsvn_client/ctx.c
(svn_client_create_context2): Create and initialize the internal client
context, including the RA session cache, along with the public context.
* subversion/libsvn_client/ra.c
(svn_client__open_ra_session_internal):
Update use of svn_client__ra_cache_open_session.
(svn_client__ra_session_release):
Update use of svn_client__ra_cache_release_session.
* subversion/libsvn_client/ra_cache.c: Include stddef.h.
(client_ra_session_t): Renamed from cached_session_t. All uses updated.
(svn_client__ra_cache_t): Removed; moved to ra_cache.h.
(cleanup_session): Remove carriage-return from debug message.
(verify_client_context, get_private_ra_cache): New.
(svn_client__ra_cache_init): Converted from svn_client__ra_cache_create
to just initialize, not allocate, the RA session cache.
(find_session_by_url): Update RA session cache parameter type and name.
(svn_client__ra_cache_open_session,
svn_client__ra_cache_release_session): Update to new signature.
Modified:
subversion/branches/reuse-ra-session/subversion/include/svn_client.h
subversion/branches/reuse-ra-session/subversion/libsvn_client/ctx.c
subversion/branches/reuse-ra-session/subversion/libsvn_client/ra.c
subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.c
subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.h
Modified: subversion/branches/reuse-ra-session/subversion/include/svn_client.h
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/include/svn_client.h?rev=1656451&r1=1656450&r2=1656451&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/include/svn_client.h
(original)
+++ subversion/branches/reuse-ra-session/subversion/include/svn_client.h Mon
Feb 2 12:34:17 2015
@@ -1050,13 +1050,6 @@ typedef struct svn_client_ctx_t
* @since New in 1.9.
*/
void *tunnel_baton;
-
- /** A RA session cache for the client operation to use.
- * This is initialized by svn_client_create_context() and should never
- * be directly used or changed.
- *
- * @since New in 1.9. */
- void *ra_cache;
} svn_client_ctx_t;
/** Initialize a client context.
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_client/ctx.c
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_client/ctx.c?rev=1656451&r1=1656450&r2=1656451&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_client/ctx.c
(original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_client/ctx.c Mon Feb
2 12:34:17 2015
@@ -84,25 +84,29 @@ svn_client_create_context2(svn_client_ct
{
svn_config_t *cfg_config;
- *ctx = apr_pcalloc(pool, sizeof(svn_client_ctx_t));
+ client_ctx_t *const private_ctx = apr_pcalloc(pool, sizeof(*private_ctx));
+ svn_client_ctx_t *const public_ctx = &private_ctx->ctx;
- (*ctx)->notify_func2 = call_notify_func;
- (*ctx)->notify_baton2 = *ctx;
+ private_ctx->magic_null = 0;
+ private_ctx->magic_id = CLIENT_CTX_MAGIC;
- (*ctx)->conflict_func2 = call_conflict_func;
- (*ctx)->conflict_baton2 = *ctx;
+ private_ctx->ctx.notify_func2 = call_notify_func;
+ private_ctx->ctx.notify_baton2 = public_ctx;
- (*ctx)->config = cfg_hash;
+ private_ctx->ctx.conflict_func2 = call_conflict_func;
+ private_ctx->ctx.conflict_baton2 = public_ctx;
+
+ private_ctx->ctx.config = cfg_hash;
if (cfg_hash)
cfg_config = svn_hash_gets(cfg_hash, SVN_CONFIG_CATEGORY_CONFIG);
else
cfg_config = NULL;
- SVN_ERR(svn_wc_context_create(&(*ctx)->wc_ctx, cfg_config, pool,
- pool));
-
- (*ctx)->ra_cache = svn_client__ra_cache_create(cfg_hash, pool);
+ SVN_ERR(svn_wc_context_create(&private_ctx->ctx.wc_ctx, cfg_config,
+ pool, pool));
+ svn_client__ra_cache_init(private_ctx, cfg_hash, pool);
+ *ctx = public_ctx;
return SVN_NO_ERROR;
}
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_client/ra.c
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_client/ra.c?rev=1656451&r1=1656450&r2=1656451&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_client/ra.c
(original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_client/ra.c Mon Feb
2 12:34:17 2015
@@ -418,7 +418,7 @@ svn_client__open_ra_session_internal(svn
don't accept corrected URLs from the RA provider. */
SVN_ERR(svn_client__ra_cache_open_session(
ra_session, attempts_left == 0 ? NULL : &corrected,
- ctx->ra_cache, base_url, uuid, cbtable, cb,
+ ctx, base_url, uuid, cbtable, cb,
result_pool, scratch_pool));
/* No error and no corrected URL? We're done here. */
@@ -451,7 +451,7 @@ svn_client__open_ra_session_internal(svn
}
else
{
- SVN_ERR(svn_client__ra_cache_open_session(ra_session, NULL,
ctx->ra_cache,
+ SVN_ERR(svn_client__ra_cache_open_session(ra_session, NULL, ctx,
base_url, uuid, cbtable,
cb, result_pool, scratch_pool));
}
@@ -1192,6 +1192,6 @@ svn_error_t *
svn_client__ra_session_release(svn_client_ctx_t *ctx,
svn_ra_session_t *session)
{
- svn_client__ra_cache_release_session(ctx->ra_cache, session);
+ svn_client__ra_cache_release_session(ctx, session);
return SVN_NO_ERROR;
}
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=1656451&r1=1656450&r2=1656451&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
Mon Feb 2 12:34:17 2015
@@ -21,6 +21,7 @@
* ====================================================================
*/
+#include <stddef.h>
#include <apr_pools.h>
#include "svn_dirent_uri.h"
@@ -35,7 +36,7 @@
#define RCTX_DBG(x)
#endif
-typedef struct cached_session_t
+typedef struct client_ra_session_t
{
svn_ra_session_t *session;
@@ -59,45 +60,53 @@ typedef struct cached_session_t
/* Accumulated progress since last session open. */
apr_off_t progress;
-} cached_session_t;
+} client_ra_session_t;
-struct svn_client__ra_cache_t
-{
- /* Hashtable of cached RA sessions. Keys are RA_SESSION_T and values
- * are CACHED_SESION_T pointers. */
- apr_hash_t *cached_session;
- apr_pool_t *pool;
- apr_hash_t *config;
-
- /* Next ID for RA sessions. Used only for diagnostics purpose. */
- int next_id;
-};
static apr_status_t
cleanup_session(void *data)
{
- cached_session_t *cache_entry = data;
+ client_ra_session_t *cache_entry = data;
cache_entry->owner_pool = NULL;
cache_entry->cb_table = NULL;
cache_entry->cb_baton = NULL;
- RCTX_DBG(("SESSION(%d): Released\r\n", cache_entry->id));
+ RCTX_DBG(("SESSION(%d): Released\n", cache_entry->id));
return APR_SUCCESS;
}
-svn_client__ra_cache_t *
-svn_client__ra_cache_create(apr_hash_t *config,
- apr_pool_t *pool)
+/* Check that the private context struct is valid. */
+static void
+verify_client_context(client_ctx_t *private_ctx)
{
- svn_client__ra_cache_t *ctx = apr_pcalloc(pool, sizeof(*ctx));
+ SVN_ERR_ASSERT_NO_RETURN(0 == private_ctx->magic_null);
+ SVN_ERR_ASSERT_NO_RETURN(CLIENT_CTX_MAGIC == private_ctx->magic_id);
+}
- ctx->pool = pool;
- ctx->cached_session = apr_hash_make(pool);
- ctx->config = config;
+/* Convert a public client context pointer to a private client context
+ pointer. */
+static client_ra_cache_t *
+get_private_ra_cache(svn_client_ctx_t *ctx)
+{
+ client_ctx_t *const private_ctx =
+ (void*)((char *)ctx - offsetof(client_ctx_t, ctx));
+ SVN_ERR_ASSERT_NO_RETURN(&private_ctx->ctx == ctx);
+ verify_client_context(private_ctx);
+ return &private_ctx->ra_cache;
+}
- return ctx;
+void
+svn_client__ra_cache_init(client_ctx_t *private_ctx,
+ apr_hash_t *config,
+ apr_pool_t *pool)
+{
+ verify_client_context(private_ctx);
+
+ private_ctx->ra_cache.pool = pool;
+ private_ctx->ra_cache.cached_session = apr_hash_make(pool);
+ private_ctx->ra_cache.config = config;
}
static svn_error_t *
@@ -106,7 +115,7 @@ get_wc_contents(void *baton,
const svn_checksum_t *checksum,
apr_pool_t *pool)
{
- cached_session_t *b = baton;
+ client_ra_session_t *b = baton;
if (!b->cb_table->get_wc_contents)
{
@@ -122,7 +131,7 @@ open_tmp_file(apr_file_t **fp,
void *baton,
apr_pool_t *pool)
{
- cached_session_t *b = baton;
+ client_ra_session_t *b = baton;
return svn_error_trace(b->cb_table->open_tmp_file(fp, b->cb_baton, pool));
}
@@ -134,7 +143,7 @@ get_wc_prop(void *baton,
const svn_string_t **value,
apr_pool_t *pool)
{
- cached_session_t *b = baton;
+ client_ra_session_t *b = baton;
if (b->cb_table->get_wc_prop)
{
@@ -157,7 +166,7 @@ push_wc_prop(void *baton,
const svn_string_t *value,
apr_pool_t *pool)
{
- cached_session_t *b = baton;
+ client_ra_session_t *b = baton;
if (b->cb_table->push_wc_prop)
{
@@ -180,7 +189,7 @@ set_wc_prop(void *baton,
const svn_string_t *value,
apr_pool_t *pool)
{
- cached_session_t *b = baton;
+ client_ra_session_t *b = baton;
if (b->cb_table->set_wc_prop)
{
return svn_error_trace(
@@ -200,7 +209,7 @@ invalidate_wc_props(void *baton,
const char *prop_name,
apr_pool_t *pool)
{
- cached_session_t *b = baton;
+ client_ra_session_t *b = baton;
if (b->cb_table->invalidate_wc_props)
{
@@ -219,7 +228,7 @@ get_client_string(void *baton,
const char **name,
apr_pool_t *pool)
{
- cached_session_t *b = baton;
+ client_ra_session_t *b = baton;
if (b->cb_table->get_client_string)
{
@@ -236,7 +245,7 @@ get_client_string(void *baton,
static svn_error_t *
cancel_callback(void *baton)
{
- cached_session_t *b = baton;
+ client_ra_session_t *b = baton;
if (b->cb_table->cancel_func)
{
@@ -254,7 +263,7 @@ progress_func(apr_off_t progress,
void *baton,
apr_pool_t *pool)
{
- cached_session_t *b = baton;
+ client_ra_session_t *b = baton;
b->progress += (progress - b->last_progress);
b->last_progress = progress;
@@ -265,17 +274,17 @@ progress_func(apr_off_t progress,
}
static svn_error_t *
-find_session_by_url(cached_session_t **cache_entry_p,
- svn_client__ra_cache_t *ctx,
+find_session_by_url(client_ra_session_t **cache_entry_p,
+ client_ra_cache_t *ra_cache,
const char *url,
apr_pool_t *scratch_pool)
{
apr_hash_index_t *hi;
- for (hi = apr_hash_first(scratch_pool, ctx->cached_session);
+ for (hi = apr_hash_first(scratch_pool, ra_cache->cached_session);
hi; hi = apr_hash_next(hi))
{
- cached_session_t *cache_entry = apr_hash_this_val(hi);
+ client_ra_session_t *cache_entry = apr_hash_this_val(hi);
if (cache_entry->owner_pool == NULL &&
svn_uri__is_ancestor(cache_entry->root_url, url))
@@ -292,7 +301,7 @@ find_session_by_url(cached_session_t **c
svn_error_t *
svn_client__ra_cache_open_session(svn_ra_session_t **session_p,
const char **corrected_p,
- svn_client__ra_cache_t *ctx,
+ svn_client_ctx_t *ctx,
const char *base_url,
const char *uuid,
svn_ra_callbacks2_t *cbtable,
@@ -300,12 +309,13 @@ svn_client__ra_cache_open_session(svn_ra
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- cached_session_t *cache_entry;
+ client_ra_cache_t *const ra_cache = get_private_ra_cache(ctx);
+ client_ra_session_t *cache_entry;
if (corrected_p)
*corrected_p = NULL;
- SVN_ERR(find_session_by_url(&cache_entry, ctx, base_url, scratch_pool));
+ SVN_ERR(find_session_by_url(&cache_entry, ra_cache, base_url, scratch_pool));
if (cache_entry)
{
@@ -349,9 +359,9 @@ svn_client__ra_cache_open_session(svn_ra
svn_ra_callbacks2_t *cbtable_sink;
svn_ra_session_t *session;
- cache_entry = apr_pcalloc(ctx->pool, sizeof(*cache_entry));
+ cache_entry = apr_pcalloc(ra_cache->pool, sizeof(*cache_entry));
- SVN_ERR(svn_ra_create_callbacks(&cbtable_sink, ctx->pool));
+ SVN_ERR(svn_ra_create_callbacks(&cbtable_sink, ra_cache->pool));
cbtable_sink->open_tmp_file = open_tmp_file;
cbtable_sink->get_wc_prop = get_wc_prop;
cbtable_sink->set_wc_prop = set_wc_prop;
@@ -367,10 +377,10 @@ svn_client__ra_cache_open_session(svn_ra
cache_entry->owner_pool = result_pool;
cache_entry->cb_table = cbtable;
cache_entry->cb_baton = callback_baton;
- cache_entry->id = ctx->next_id;
+ cache_entry->id = ra_cache->next_id;
SVN_ERR(svn_ra_open4(&session, corrected_p, base_url, uuid, cbtable_sink,
- cache_entry, ctx->config, ctx->pool));
+ cache_entry, ra_cache->config, ra_cache->pool));
if (corrected_p && *corrected_p)
{
@@ -382,13 +392,13 @@ svn_client__ra_cache_open_session(svn_ra
cache_entry->session = session;
SVN_ERR(svn_ra_get_repos_root2(session, &cache_entry->root_url,
- ctx->pool));
+ ra_cache->pool));
RCTX_DBG(("SESSION(%d): Open('%s')\n", cache_entry->id, base_url));
- apr_hash_set(ctx->cached_session, &cache_entry->session,
+ apr_hash_set(ra_cache->cached_session, &cache_entry->session,
sizeof(cache_entry->session), cache_entry);
- ctx->next_id++;
+ ++ra_cache->next_id;
}
cache_entry->owner_pool = result_pool;
@@ -404,11 +414,12 @@ svn_client__ra_cache_open_session(svn_ra
}
void
-svn_client__ra_cache_release_session(svn_client__ra_cache_t *ctx,
+svn_client__ra_cache_release_session(svn_client_ctx_t *ctx,
svn_ra_session_t *session)
{
- cached_session_t *cache_entry = apr_hash_get(ctx->cached_session,
- &session, sizeof(session));
+ client_ra_cache_t *const ra_cache = get_private_ra_cache(ctx);
+ client_ra_session_t *cache_entry = apr_hash_get(ra_cache->cached_session,
+ &session, sizeof(session));
SVN_ERR_ASSERT_NO_RETURN(cache_entry != NULL);
SVN_ERR_ASSERT_NO_RETURN(cache_entry->owner_pool != NULL);
Modified:
subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.h
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.h?rev=1656451&r1=1656450&r2=1656451&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.h
(original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_client/ra_cache.h
Mon Feb 2 12:34:17 2015
@@ -27,6 +27,7 @@
#include <apr_pools.h>
#include "svn_auth.h"
+#include "svn_client.h"
#include "svn_ra.h"
#include "svn_types.h"
@@ -34,28 +35,65 @@
extern "C" {
#endif /* __cplusplus */
-typedef struct svn_client__ra_cache_t svn_client__ra_cache_t;
+typedef struct client_ra_cache_t
+{
+ /* Hashtable of cached RA sessions. Keys are RA_SESSION_T and values
+ * are CLIENT_RA_SESION_T pointers. */
+ apr_hash_t *cached_session;
+ apr_pool_t *pool;
+ apr_hash_t *config;
-/* Allocates ra_cache structure in POOL. Will use CONFIG for
- for RA sessions created in this context. */
-svn_client__ra_cache_t *
-svn_client__ra_cache_create(apr_hash_t *config,
- apr_pool_t *pool);
+ /* Next ID for RA sessions. Used only for diagnostics purpose. */
+ int next_id;
+} client_ra_cache_t;
+
+
+/* Private client context.
+ * This is what is actually allocated by context constructor. */
+typedef struct client_ctx_t
+{
+ /* Reserved field, always zero, to detect misuse of the private
+ context as a public client context. */
+ apr_uint64_t magic_null;
+
+ /* Reserved field, always set to a known magic number, to identify
+ this struct as the private client context. */
+ apr_uint64_t magic_id;
+
+ /* The RA session cache. */
+ client_ra_cache_t ra_cache;
+
+ /* The public context. */
+ svn_client_ctx_t ctx;
+} client_ctx_t;
+
+
+#define CLIENT_CTX_MAGIC APR_UINT64_C(0xDEADBEEF600DF00D)
+
+
+/* Initializes the CTX->ra_cache structure. Will use CONFIG for for RA
+ sessions created in this context. Assumes that CTX was allocated
+ from POOL. */
+void
+svn_client__ra_cache_init(client_ctx_t *private_ctx,
+ apr_hash_t *config,
+ apr_pool_t *pool);
/* Open new repository access session to the repository at BASE_URL or
- reuses existing session cached in CTX.
+ reuses existing session cached in the private owner of CTX.
The function behavior is the same as svn_ra_open4() with ability
to reuse sessions for same repository.
- The created session will be automatically returned to CTX on RESULT_POOL
- cleanup or by explicit svn_client__ra_cache_release_session() call.
+ The created session will be automatically returned to the list of
+ reusable sessions on RESULT_POOL cleanup or by explicit
+ svn_client__ra_cache_release_session() call.
Uses SCRATCH_POOL for temporary allocations. */
svn_error_t *
svn_client__ra_cache_open_session(svn_ra_session_t **session_p,
const char **corrected_p,
- svn_client__ra_cache_t *ctx,
+ svn_client_ctx_t *ctx,
const char *base_url,
const char *uuid,
svn_ra_callbacks2_t *cbtable,
@@ -63,9 +101,9 @@ svn_client__ra_cache_open_session(svn_ra
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-/* Returns RA SESSION back to CTX. */
+/* Returns RA SESSION back to the cache in the private owner of CTX. */
void
-svn_client__ra_cache_release_session(svn_client__ra_cache_t *ctx,
+svn_client__ra_cache_release_session(svn_client_ctx_t *ctx,
svn_ra_session_t *session);
#ifdef __cplusplus