You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2017/05/27 14:14:56 UTC
svn commit: r1796399 - in /subversion/trunk/subversion:
libsvn_fs_x/batch_fsync.c libsvn_ra/ra_loader.c libsvn_repos/dump.c
libsvn_subr/pool.c svnadmin/svnadmin.c
Author: stefan2
Date: Sat May 27 14:14:55 2017
New Revision: 1796399
URL: http://svn.apache.org/viewvc?rev=1796399&view=rev
Log:
m
Modified:
subversion/trunk/subversion/libsvn_fs_x/batch_fsync.c
subversion/trunk/subversion/libsvn_ra/ra_loader.c
subversion/trunk/subversion/libsvn_repos/dump.c
subversion/trunk/subversion/libsvn_subr/pool.c
subversion/trunk/subversion/svnadmin/svnadmin.c
Modified: subversion/trunk/subversion/libsvn_fs_x/batch_fsync.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/batch_fsync.c?rev=1796399&r1=1796398&r2=1796399&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/batch_fsync.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/batch_fsync.c Sat May 27 14:14:55 2017
@@ -228,6 +228,7 @@ struct svn_fs_x__batch_fsync_t
/* Thread pool to execute the fsync tasks. */
static apr_thread_pool_t *thread_pool = NULL;
+static apr_pool_t *threadsafe_pool = NULL;
#endif
@@ -247,14 +248,18 @@ static svn_atomic_t thread_pool_initiali
static apr_status_t
thread_pool_pre_cleanup(void *data)
{
+ apr_status_t result;
apr_thread_pool_t *tp = thread_pool;
if (!thread_pool)
return APR_SUCCESS;
thread_pool = NULL;
+ threadsafe_pool = NULL;
thread_pool_initialized = FALSE;
- return apr_thread_pool_destroy(tp);
+ result = apr_thread_pool_destroy(tp);
+ apr_sleep(1000);
+ return result;
}
#endif
@@ -267,7 +272,11 @@ create_thread_pool(void *baton,
#if APR_HAS_THREADS
/* The thread-pool must be allocated from a thread-safe pool.
GLOBAL_POOL may be single-threaded, though. */
- apr_pool_t *pool = svn_pool_create(NULL);
+ apr_allocator_t *allocator = apr_pool_allocator_get(owning_pool);
+ apr_pool_t *pool = apr_allocator_mutex_get(allocator)
+ ? owning_pool
+ : svn_pool_create(NULL);
+ pool = owning_pool;
/* This thread pool will get cleaned up automatically when GLOBAL_POOL
gets cleared. No additional cleanup callback is needed. */
@@ -277,8 +286,9 @@ create_thread_pool(void *baton,
/* Work around an APR bug: The cleanup must happen in the pre-cleanup
hook instead of the normal cleanup hook. Otherwise, the sub-pools
containing the thread objects would already be invalid. */
- apr_pool_pre_cleanup_register(pool, NULL, thread_pool_pre_cleanup);
apr_pool_pre_cleanup_register(owning_pool, NULL, thread_pool_pre_cleanup);
+ if (pool != owning_pool)
+ apr_pool_pre_cleanup_register(pool, NULL, thread_pool_pre_cleanup);
/* let idle threads linger for a while in case more requests are
coming in */
Modified: subversion/trunk/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra/ra_loader.c?rev=1796399&r1=1796398&r2=1796399&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/trunk/subversion/libsvn_ra/ra_loader.c Sat May 27 14:14:55 2017
@@ -56,7 +56,10 @@
#include "private/svn_ra_private.h"
#include "svn_private_config.h"
-
+#ifdef SVN_LIBSVN_RA_LINKS_RA_LOCAL
+/* for svn_fs_initialize(). */
+#include "svn_fs.h"
+#endif
/* These are the URI schemes that the respective libraries *may* support.
@@ -237,6 +240,20 @@ svn_error_t *svn_ra_initialize(apr_pool_
we're going to use it. */
SVN_ERR(svn_dso_initialize2());
#endif
+
+#ifdef SVN_LIBSVN_RA_LINKS_RA_LOCAL
+ /* Make sure we initialize the FS layer with an appropriate base pool.
+ * POOL will live long enough but can be cleaned up explicitly by the
+ * using application. That prevents cleanup / threading races during
+ * the termination phase. See also http://www.luke1410.de/blog/?p=95
+ *
+ * The client does not know that the FS layer needs to be initialized
+ * when it wants to use RA local. Due to missing interface guarantees,
+ * we cannot pass an appropriate pool to ra_local's initialization
+ * routine. Hence the explicit call here.
+ */
+ SVN_ERR(svn_fs_initialize(pool));
+#endif
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/dump.c?rev=1796399&r1=1796398&r2=1796399&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/dump.c (original)
+++ subversion/trunk/subversion/libsvn_repos/dump.c Sat May 27 14:14:55 2017
@@ -20,8 +20,9 @@
* ====================================================================
*/
-
#include <stdarg.h>
+#include <apr_thread_pool.h>
+#include <apr_time.h>
#include "svn_private_config.h"
#include "svn_pools.h"
@@ -44,6 +45,7 @@
#include "private/svn_sorts_private.h"
#include "private/svn_utf_private.h"
#include "private/svn_cache.h"
+#include "private/svn_subr_private.h"
#define ARE_VALID_COPY_ARGS(p,r) ((p) && SVN_IS_VALID_REVNUM(r))
@@ -2391,6 +2393,202 @@ report_error(svn_revnum_t revision,
}
}
+typedef struct verification_job_t
+{
+ svn_fs_t *fs;
+ svn_revnum_t first_rev;
+ svn_revnum_t last_rev;
+ svn_revnum_t start_rev;
+ svn_boolean_t check_normalization;
+ svn_repos_notify_func_t notify_func;
+ void *notify_baton;
+ svn_cancel_func_t cancel_func;
+ void *cancel_baton;
+ svn_root_pools__t *pools;
+ svn_error_t *result;
+ svn_mutex__t *mutex;
+ apr_array_header_t *fs_instances;
+} verification_job_t;
+
+typedef struct fs_instance_t
+{
+ svn_fs_t *fs;
+ apr_pool_t *pool;
+} fs_instance_t;
+
+/* Thread-pool task Flush the to_sync_t instance given by DATA. */
+static void * APR_THREAD_FUNC
+verify_task(apr_thread_t *tid,
+ void *data)
+{
+ verification_job_t *baton = data;
+ fs_instance_t *instance;
+ svn_error_t *err = SVN_NO_ERROR;
+
+ SVN_ERR(svn_mutex__lock(baton->mutex));
+ if (baton->fs_instances->nelts)
+ {
+ instance = *(fs_instance_t **)apr_array_pop(baton->fs_instances);
+ }
+ else
+ {
+ apr_pool_t *pool = svn_root_pools__acquire_pool(baton->pools);
+ instance = apr_pcalloc(pool, sizeof(*instance));
+ instance->pool = pool;
+
+ SVN_ERR(svn_fs_open2(&instance->fs,
+ svn_fs_path(baton->fs, pool),
+ svn_fs_config(baton->fs, pool),
+ pool, pool));
+ }
+ SVN_ERR(svn_mutex__unlock(baton->mutex, SVN_NO_ERROR));
+
+ if (!err)
+ {
+ svn_revnum_t rev;
+ apr_pool_t *iterpool = svn_pool_create(instance->pool);
+ for (rev = baton->first_rev; rev < baton->last_rev; ++rev)
+ {
+ svn_pool_clear(iterpool);
+ err = svn_error_trace(verify_one_revision(instance->fs,
+ rev,
+ baton->notify_func,
+ baton->notify_baton,
+ baton->start_rev,
+ baton->check_normalization,
+ baton->cancel_func,
+ baton->cancel_baton,
+ iterpool));
+ }
+ svn_pool_destroy(iterpool);
+ }
+ baton->result = err;
+
+ SVN_ERR(svn_mutex__lock(baton->mutex));
+ APR_ARRAY_PUSH(baton->fs_instances, fs_instance_t *) = instance;
+ SVN_ERR(svn_mutex__unlock(baton->mutex, SVN_NO_ERROR));
+
+ return NULL;
+}
+
+#define WRAP_APR_ERR(x,msg) \
+ { \
+ apr_status_t status_ = (x); \
+ if (status_) \
+ return svn_error_wrap_apr(status_, msg); \
+ }
+
+static svn_error_t *
+verify_mt(svn_fs_t *fs,
+ svn_revnum_t start_rev,
+ svn_revnum_t end_rev,
+ svn_boolean_t check_normalization,
+ svn_repos_notify_t *notify,
+ svn_repos_notify_func_t notify_func,
+ void *notify_baton,
+ svn_repos_verify_callback_t verify_callback,
+ void *verify_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool)
+{
+ svn_revnum_t rev;
+ svn_root_pools__t *root_pools;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ svn_error_t *err = SVN_NO_ERROR;
+ apr_array_header_t *jobs = apr_array_make(scratch_pool,
+ end_rev - start_rev + 1,
+ sizeof(verification_job_t));
+
+ /* Number of tasks sent to the thread pool. */
+ int tasks = 0;
+ int i;
+
+#if APR_HAS_THREADS
+ apr_thread_pool_t *thread_pool = NULL;
+ enum { MAX_THREADS = 24, STRIDE = 5 };
+
+ /* The thread-pool must be allocated from a thread-safe pool.
+ GLOBAL_POOL may be single-threaded, though. */
+ apr_pool_t *pool = svn_pool_create(NULL);
+
+ svn_mutex__t * mutex;
+ apr_array_header_t *fs_instances = apr_array_make(pool, MAX_THREADS,
+ sizeof(fs_instance_t *));
+
+ SVN_ERR(svn_mutex__init(&mutex, TRUE, pool));
+
+ /* This thread pool will get cleaned up automatically when GLOBAL_POOL
+ gets cleared. No additional cleanup callback is needed. */
+ WRAP_APR_ERR(apr_thread_pool_create(&thread_pool, 0, MAX_THREADS, pool),
+ _("Can't create verification thread pool"));
+
+#endif
+
+ SVN_ERR(svn_root_pools__create(&root_pools));
+
+ for (rev = start_rev; rev <= end_rev && err == SVN_NO_ERROR; rev += STRIDE)
+ {
+ apr_status_t status = APR_SUCCESS;
+ verification_job_t *job = apr_array_push(jobs);
+
+ job->fs = fs;
+ job->first_rev = rev;
+ job->last_rev = MIN(rev + STRIDE, end_rev + 1);
+ job->start_rev = start_rev;
+ job->check_normalization = check_normalization;
+ job->notify_func = notify_func;
+ job->notify_baton = notify_baton;
+ job->cancel_func = cancel_func;
+ job->cancel_baton = cancel_baton;
+ job->pools = root_pools;
+ job->result = SVN_NO_ERROR;
+ job->mutex = mutex;
+ job->fs_instances = fs_instances;
+
+ status = apr_thread_pool_push(thread_pool, verify_task, job, 0, NULL);
+ if (status)
+ job->result = svn_error_wrap_apr(status, _("Can't push task"));
+ else
+ tasks++;
+ }
+
+ while (apr_thread_pool_tasks_run_count(thread_pool) < tasks)
+ apr_sleep(10000);
+
+ for (i = 0; i < tasks; i++)
+ {
+ verification_job_t *job = &APR_ARRAY_IDX(jobs, i, verification_job_t);
+ err = job->result;
+ rev = job->first_rev;
+ svn_pool_clear(iterpool);
+
+ if (err && err->apr_err == SVN_ERR_CANCELLED)
+ {
+ ;
+ }
+ else if (err)
+ {
+ err = report_error(rev, err, verify_callback, verify_baton,
+ iterpool);
+ }
+ else if (notify_func)
+ {
+ /* Tell the caller that we're done with this revision. */
+ notify->revision = rev;
+ notify_func(notify_baton, notify, iterpool);
+ }
+
+ svn_error_clear(err);
+ }
+
+ WRAP_APR_ERR(apr_thread_pool_destroy(thread_pool),
+ _("Can't destroy verification thread pool"));
+ svn_pool_destroy(pool);
+
+ return svn_error_trace(err);
+}
+
svn_error_t *
svn_repos_verify_fs3(svn_repos_t *repos,
svn_revnum_t start_rev,
@@ -2470,32 +2668,44 @@ svn_repos_verify_fs3(svn_repos_t *repos,
}
if (!metadata_only)
- for (rev = start_rev; rev <= end_rev; rev++)
- {
- svn_pool_clear(iterpool);
-
- /* Wrapper function to catch the possible errors. */
- err = verify_one_revision(fs, rev, notify_func, notify_baton,
- start_rev, check_normalization,
- cancel_func, cancel_baton,
- iterpool);
+ {
+#if APR_HAS_THREADS
+ if (start_rev < end_rev)
+ {
+ SVN_ERR(verify_mt(fs, start_rev, end_rev, check_normalization,
+ notify, notify_func, notify_baton,
+ verify_callback, verify_baton,
+ cancel_func, cancel_baton, iterpool));
+ }
+ else
+#endif
+ for (rev = start_rev; rev <= end_rev; rev++)
+ {
+ svn_pool_clear(iterpool);
- if (err && err->apr_err == SVN_ERR_CANCELLED)
- {
- return svn_error_trace(err);
- }
- else if (err)
- {
- SVN_ERR(report_error(rev, err, verify_callback, verify_baton,
- iterpool));
- }
- else if (notify_func)
- {
- /* Tell the caller that we're done with this revision. */
- notify->revision = rev;
- notify_func(notify_baton, notify, iterpool);
- }
- }
+ /* Wrapper function to catch the possible errors. */
+ err = verify_one_revision(fs, rev, notify_func, notify_baton,
+ start_rev, check_normalization,
+ cancel_func, cancel_baton,
+ iterpool);
+
+ if (err && err->apr_err == SVN_ERR_CANCELLED)
+ {
+ return svn_error_trace(err);
+ }
+ else if (err)
+ {
+ SVN_ERR(report_error(rev, err, verify_callback, verify_baton,
+ iterpool));
+ }
+ else if (notify_func)
+ {
+ /* Tell the caller that we're done with this revision. */
+ notify->revision = rev;
+ notify_func(notify_baton, notify, iterpool);
+ }
+ }
+ }
/* We're done. */
if (notify_func)
Modified: subversion/trunk/subversion/libsvn_subr/pool.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/pool.c?rev=1796399&r1=1796398&r2=1796399&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/pool.c (original)
+++ subversion/trunk/subversion/libsvn_subr/pool.c Sat May 27 14:14:55 2017
@@ -136,7 +136,7 @@ svn_pool_create_allocator(svn_boolean_t
* if we want thread-safety for that mutex. */
#if APR_HAS_THREADS
- if (thread_safe)
+ if (1)
{
apr_thread_mutex_t *mutex;
apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, pool);
Modified: subversion/trunk/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnadmin/svnadmin.c?rev=1796399&r1=1796398&r2=1796399&view=diff
==============================================================================
--- subversion/trunk/subversion/svnadmin/svnadmin.c (original)
+++ subversion/trunk/subversion/svnadmin/svnadmin.c Sat May 27 14:14:55 2017
@@ -2992,7 +2992,7 @@ sub_main(int *exit_code, int argc, const
svn_cache_config_t settings = *svn_cache_config_get();
settings.cache_size = opt_state.memory_cache_size;
- settings.single_threaded = TRUE;
+ settings.single_threaded = FALSE;
svn_cache_config_set(&settings);
}
Re: svn commit: r1796399 - in /subversion/trunk/subversion:
libsvn_fs_x/batch_fsync.c libsvn_ra/ra_loader.c libsvn_repos/dump.c
libsvn_subr/pool.c svnadmin/svnadmin.c
Posted by Stefan Fuhrmann <st...@apache.org>.
Oops.. sorry!
A test script ran commit in the wrong folder :/
Thanks for notifying!
-- Stefan^2.
On 27.05.2017 16:24, Stefan Sperling wrote:
> On Sat, May 27, 2017 at 02:14:56PM -0000, stefan2@apache.org wrote:
>> Author: stefan2
>> Date: Sat May 27 14:14:55 2017
>> New Revision: 1796399
>>
>> URL: http://svn.apache.org/viewvc?rev=1796399&view=rev
>> Log:
>> m
>>
>
> Hmmm? :)
>
>> Modified:
>> subversion/trunk/subversion/libsvn_fs_x/batch_fsync.c
>> subversion/trunk/subversion/libsvn_ra/ra_loader.c
>> subversion/trunk/subversion/libsvn_repos/dump.c
>> subversion/trunk/subversion/libsvn_subr/pool.c
>> subversion/trunk/subversion/svnadmin/svnadmin.c
>
Re: svn commit: r1796399 - in /subversion/trunk/subversion:
libsvn_fs_x/batch_fsync.c libsvn_ra/ra_loader.c libsvn_repos/dump.c
libsvn_subr/pool.c svnadmin/svnadmin.c
Posted by Stefan Sperling <st...@elego.de>.
On Sat, May 27, 2017 at 02:14:56PM -0000, stefan2@apache.org wrote:
> Author: stefan2
> Date: Sat May 27 14:14:55 2017
> New Revision: 1796399
>
> URL: http://svn.apache.org/viewvc?rev=1796399&view=rev
> Log:
> m
>
Hmmm? :)
> Modified:
> subversion/trunk/subversion/libsvn_fs_x/batch_fsync.c
> subversion/trunk/subversion/libsvn_ra/ra_loader.c
> subversion/trunk/subversion/libsvn_repos/dump.c
> subversion/trunk/subversion/libsvn_subr/pool.c
> subversion/trunk/subversion/svnadmin/svnadmin.c