FreeBSD/contrib/subversion/subversion/libsvn_repos/repos.c
/* For historical reasons, for the Berkeley DB backend, this code uses
 * repository locking, which is motivated by the need to support the
 * Berkeley DB error DB_RUN_RECOVERY.  (FSFS takes care of locking
 * itself, inside its implementation of svn_fs_recover.)  Here's how
 * it works:
 *
 * Every accessor of a repository's database takes out a shared lock
 * on the repository -- both readers and writers get shared locks, and
 * there can be an unlimited number of shared locks simultaneously.
 *
 * Sometimes, a db access returns the error DB_RUN_RECOVERY.  When
 * this happens, we need to run svn_fs_recover() on the db
 * with no other accessors present.  So we take out an exclusive lock
 * on the repository.  From the moment we request the exclusive lock,
 * no more shared locks are granted, and when the last shared lock
 * disappears, the exclusive lock is granted.  As soon as we get it,
 * we can run recovery.
 *
 * We assume that once any berkeley call returns DB_RUN_RECOVERY, they
 * all do, until recovery is run.
 */
For historical reasons, for the Berkeley DB backend, this code uses
repository locking, which is motivated by the need to support the
Berkeley DB error DB_RUN_RECOVERY.  (FSFS takes care of locking
itself, inside its implementation of svn_fs_recover.)  Here's how
it works.

Every accessor of a repository's database takes out a shared lock
on the repository -- both readers and writers get shared locks, and
there can be an unlimited number of shared locks simultaneously.

Sometimes, a db access returns the error DB_RUN_RECOVERY.  When
this happens, we need to run svn_fs_recover() on the db
with no other accessors present.  So we take out an exclusive lock
on the repository.  From the moment we request the exclusive lock,
no more shared locks are granted, and when the last shared lock
disappears, the exclusive lock is granted.  As soon as we get it,
we can run recovery.

We assume that once any berkeley call returns DB_RUN_RECOVERY, they
all do, until recovery is run.
For historical reasons for the Berkeley DB backend this code uses repository locking which is motivated by the need to support the Berkeley DB error DB_RUN_RECOVERY . ( FSFS takes care of locking itself inside its implementation of svn_fs_recover . ) Here ' s how it works . Every accessor of a repository ' s database takes out a shared lock on the repository -- both readers and writers get shared locks and there can be an unlimited number of shared locks simultaneously . Sometimes a db access returns the error DB_RUN_RECOVERY . When this happens we need to run svn_fs_recover () on the db with no other accessors present . So we take out an exclusive lock on the repository . From the moment we request the exclusive lock no more shared locks are granted and when the last shared lock disappears the exclusive lock is granted . As soon as we get it we can run recovery . We assume that once any berkeley call returns DB_RUN_RECOVERY they all do until recovery is run .
svn_error_t *
svn_repos_recover4(const char *path,
                   svn_boolean_t nonblocking,
                   svn_repos_notify_func_t notify_func,
                   void *notify_baton,
                   svn_cancel_func_t cancel_func,
                   void * cancel_baton,
                   apr_pool_t *pool)
{
  svn_repos_t *repos;
  apr_pool_t *subpool = svn_pool_create(pool);
  SVN_ERR(get_repos(&repos, path, TRUE, nonblocking,
                    FALSE,    
                    NULL,
                    subpool, subpool));
  if (notify_func)
    {
      svn_repos_notify_t *notify = svn_repos_notify_create(
                                    svn_repos_notify_mutex_acquired, subpool);
      notify_func(notify_baton, notify, subpool);
      notify->action = svn_repos_notify_recover_start;
      notify_func(notify_baton, notify, subpool);
    }
  SVN_ERR(svn_fs_recover(repos->db_path, cancel_func, cancel_baton, subpool));
  svn_pool_destroy(subpool);
  return SVN_NO_ERROR;
}
svn_error_t * svn_repos_recover4 ( const char * path , svn_boolean_t nonblocking , svn_repos_notify_func_t notify_func , void * notify_baton , svn_cancel_func_t cancel_func , void * cancel_baton , apr_pool_t * pool ) { svn_repos_t * repos ; apr_pool_t * subpool = svn_pool_create ( pool ) ; SVN_ERR ( get_repos ( & repos , path , TRUE , nonblocking , FALSE , NULL , subpool , subpool ) ) ; if ( notify_func ) { svn_repos_notify_t * notify = svn_repos_notify_create ( svn_repos_notify_mutex_acquired , subpool ) ; notify_func ( notify_baton , notify , subpool ) ; notify -> action = svn_repos_notify_recover_start ; notify_func ( notify_baton , notify , subpool ) ; } SVN_ERR ( svn_fs_recover ( repos -> db_path , cancel_func , cancel_baton , subpool ) ) ; svn_pool_destroy ( subpool ) ; return SVN_NO_ERROR ; }
For historical reasons, for the Berkeley DB backend, this code uses
 repository locking, which is motivated by the need to support the
 Berkeley DB error DB_RUN_RECOVERY.
For historical reasons for the Berkeley DB backend this code uses repository locking which is motivated by the need to support the Berkeley DB error DB_RUN_RECOVERY .
/* Fetch a repository object; for the Berkeley DB backend, it is
     initialized with an EXCLUSIVE lock on the database.  This will at
     least prevent others from trying to read or write to it while we
     run recovery. (Other backends should do their own locking; see
     lock_repos.) */ /* don't try to open the db yet. */ /* We notify *twice* here, because there are two different logistical
         actions occuring. */ /* Recover the database to a consistent state. */ /* Close shop and free the subpool, to release the exclusive lock. */