cmpil...@apache.org wrote on Wed, Apr 03, 2013 at 17:51:56 -0000: > Author: cmpilato > Date: Wed Apr 3 17:51:56 2013 > New Revision: 1464122 > > URL: http://svn.apache.org/r1464122 > Log: > Avoid parsing the hooks-env file multiple times for closely-knit hook > invocations, specifically the pre-/post- pairs for commit, revprop > change, lock, and unlock operations. > > * subversion/libsvn_repos/repos.h, > * subversion/libsvn_repos/hooks.c > (svn_repos__parse_hooks_env): Was parse_hooks_env(). > (svn_repos__hooks_start_commit, > svn_repos__hooks_pre_commit, > svn_repos__hooks_post_commit, > svn_repos__hooks_pre_revprop_change, > svn_repos__hooks_post_revprop_change, > svn_repos__hooks_pre_lock, > svn_repos__hooks_post_lock, > svn_repos__hooks_pre_unlock, > svn_repos__hooks_post_unlock): Add 'hooks_env' parameter, used now > instead of calling parse_hooks_env() from within. > > * subversion/libsvn_repos/commit.c > (complete_cb, svn_repos__get_commit_ev2): Call > svn_repos__parse_hooks_env(), and update calls to hook wrapper > functions. > > * subversion/libsvn_repos/fs-wrap.c > (svn_repos_fs_commit_txn, svn_repos_fs_begin_txn_for_commit2, > svn_repos_fs_change_rev_prop4, svn_repos_fs_lock, svn_repos_fs_unlock): > Call svn_repos__parse_hooks_env(), and update calls to hook wrapper > functions. > > * subversion/libsvn_repos/load-fs-vtable.c > (close_revision): Call svn_repos__parse_hooks_env(), and update > calls to hook wrapper functions. > > Modified: > subversion/trunk/subversion/libsvn_repos/commit.c > subversion/trunk/subversion/libsvn_repos/fs-wrap.c > subversion/trunk/subversion/libsvn_repos/hooks.c > subversion/trunk/subversion/libsvn_repos/load-fs-vtable.c > subversion/trunk/subversion/libsvn_repos/repos.h > > Modified: subversion/trunk/subversion/libsvn_repos/commit.c > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/commit.c?rev=1464122&r1=1464121&r2=1464122&view=diff > ============================================================================== > --- subversion/trunk/subversion/libsvn_repos/commit.c (original) > +++ subversion/trunk/subversion/libsvn_repos/commit.c Wed Apr 3 17:51:56 2013 > @@ -1295,10 +1295,16 @@ complete_cb(void *baton, > const char *conflict_path; > svn_error_t *err; > const char *post_commit_errstr; > + apr_hash_t *hooks_env; > + > + /* Parse the hooks-env file (if any). */ > + SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, eb->repos->hooks_env_path, > + scratch_pool, scratch_pool)); > > /* The transaction has been fully edited. Let the pre-commit hook > have a look at the thing. */ > - SVN_ERR(svn_repos__hooks_pre_commit(eb->repos, eb->txn_name, > scratch_pool)); > + SVN_ERR(svn_repos__hooks_pre_commit(eb->repos, hooks_env, > + eb->txn_name, scratch_pool)); > > /* Hook is done. Let's do the actual commit. */ > SVN_ERR(svn_fs__editor_commit(&revision, &post_commit_err, &conflict_path, > @@ -1314,8 +1320,8 @@ complete_cb(void *baton, > Other errors may have occurred within the FS (specified by the > POST_COMMIT_ERR localvar), but we need to run the hooks. */ > SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(revision)); > - err = svn_repos__hooks_post_commit(eb->repos, revision, eb->txn_name, > - scratch_pool); > + err = svn_repos__hooks_post_commit(eb->repos, hooks_env, revision, > + eb->txn_name, scratch_pool); > if (err) > err = svn_error_create(SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED, err, > _("Commit succeeded, but post-commit hook > failed")); > @@ -1405,6 +1411,11 @@ svn_repos__get_commit_ev2(svn_editor_t * > }; > struct ev2_baton *eb; > const svn_string_t *author; > + apr_hash_t *hooks_env; > + > + /* Parse the hooks-env file (if any). */ > + SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path, > + scratch_pool, scratch_pool)); > > /* Can the user modify the repository at all? */ > /* ### check against AUTHZ. */ > @@ -1428,7 +1439,8 @@ svn_repos__get_commit_ev2(svn_editor_t * > SVN_ERR(apply_revprops(repos->fs, eb->txn_name, revprops, scratch_pool)); > > /* Okay... some access is allowed. Let's run the start-commit hook. */ > - SVN_ERR(svn_repos__hooks_start_commit(repos, author ? author->data : NULL, > + SVN_ERR(svn_repos__hooks_start_commit(repos, hooks_env, > + author ? author->data : NULL, > repos->client_capabilities, > eb->txn_name, scratch_pool)); > > > Modified: subversion/trunk/subversion/libsvn_repos/fs-wrap.c > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/fs-wrap.c?rev=1464122&r1=1464121&r2=1464122&view=diff > ============================================================================== > --- subversion/trunk/subversion/libsvn_repos/fs-wrap.c (original) > +++ subversion/trunk/subversion/libsvn_repos/fs-wrap.c Wed Apr 3 17:51:56 > 2013 > @@ -54,12 +54,17 @@ svn_repos_fs_commit_txn(const char **con > apr_hash_t *props; > apr_pool_t *iterpool; > apr_hash_index_t *hi; > + apr_hash_t *hooks_env; > > *new_rev = SVN_INVALID_REVNUM; > > + /* Parse the hooks-env file (if any). */ > + SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path, > + pool, pool)); > + > /* Run pre-commit hooks. */ > SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool)); > - SVN_ERR(svn_repos__hooks_pre_commit(repos, txn_name, pool)); > + SVN_ERR(svn_repos__hooks_pre_commit(repos, hooks_env, txn_name, pool)); > > /* Remove any ephemeral transaction properties. */ > SVN_ERR(svn_fs_txn_proplist(&props, txn, pool)); > @@ -85,7 +90,8 @@ svn_repos_fs_commit_txn(const char **con > return err; > > /* Run post-commit hooks. */ > - if ((err2 = svn_repos__hooks_post_commit(repos, *new_rev, txn_name, pool))) > + if ((err2 = svn_repos__hooks_post_commit(repos, hooks_env, > + *new_rev, txn_name, pool))) > { > err2 = svn_error_create > (SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED, err2, > @@ -110,6 +116,11 @@ svn_repos_fs_begin_txn_for_commit2(svn_f > apr_array_header_t *revprops; > const char *txn_name; > svn_string_t *author = svn_hash_gets(revprop_table, > SVN_PROP_REVISION_AUTHOR); > + apr_hash_t *hooks_env; > + > + /* Parse the hooks-env file (if any). */ > + SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path, > + pool, pool)); > > /* Begin the transaction, ask for the fs to do on-the-fly lock checks. > We fetch its name, too, so the start-commit hook can use it. */ > @@ -124,7 +135,8 @@ svn_repos_fs_begin_txn_for_commit2(svn_f > SVN_ERR(svn_repos_fs_change_txn_props(*txn_p, revprops, pool)); > > /* Run start-commit hooks. */ > - SVN_ERR(svn_repos__hooks_start_commit(repos, author ? author->data : NULL, > + SVN_ERR(svn_repos__hooks_start_commit(repos, hooks_env, > + author ? author->data : NULL, > repos->client_capabilities, txn_name, > pool)); > return SVN_NO_ERROR; > @@ -317,6 +329,7 @@ svn_repos_fs_change_rev_prop4(svn_repos_ > { > const svn_string_t *old_value; > char action; > + apr_hash_t *hooks_env = NULL; >
IMO would be better not to initialise this at declaration: all codepaths that use the value also initialise it first. The same might apply to the load-fs-vtable.c:close_revision() changes. > Modified: subversion/trunk/subversion/libsvn_repos/repos.h > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/repos.h?rev=1464122&r1=1464121&r2=1464122&view=diff > ============================================================================== > --- subversion/trunk/subversion/libsvn_repos/repos.h (original) > +++ subversion/trunk/subversion/libsvn_repos/repos.h Wed Apr 3 17:51:56 2013 > @@ -161,9 +161,25 @@ struct svn_repos_t > > /*** Hook-running Functions ***/ > > +/* Set *HOOKS_ENV_P to the parsed contents of the hooks-env file > + LOCAL_ABSPATH, allocated in RESULT_POOL. (This result is suitable > + for delivery to the various hook wrapper functions which accept a > + 'hooks_env' parameter.) > + As noted on IRC, suggesting to promise setting HOOKS_ENV_P to NULL if local_abspath is NULL, since callers depend on that. > + Use SCRATCH_POOL for temporary allocations. */ > +svn_error_t * > +svn_repos__parse_hooks_env(apr_hash_t **hooks_env_p, > + const char *local_abspath, > + apr_pool_t *result_pool, > + apr_pool_t *scratch_pool); > +