/* trail.c : backing out of aborted Berkeley DB transactions
 *
 * ====================================================================
 * Copyright (c) 2000-2002 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */

#include "db.h"
#include "apr_pools.h"
#include "svn_pools.h"
#include "svn_fs.h"
#include "fs.h"
#include "err.h"
#include "trail.h"


/* A single action to be undone.  Actions are chained so that later
   actions point to earlier actions.  Thus, walking the chain and
   applying the functions should undo actions in the reverse of the
   order they were performed.  */
struct undo {

  /* A bitmask indicating when this action should be run.  */
  enum {
    undo_on_failure = 1,
    undo_on_success = 2,
  } when;

  void (*func) (void *baton);
  void *baton;
  struct undo *prev;
};


static svn_error_t *
begin_trail (trail_t **trail_p,
             svn_fs_t *fs,
             apr_pool_t *pool)
{
  trail_t *trail = apr_pcalloc (pool, sizeof (*trail));

  trail->pool = svn_pool_create (pool);
  trail->undo = 0;
  SVN_ERR (DB_WRAP (fs, "beginning Berkeley DB transaction",
                    fs->env->txn_begin (fs->env, 0, &trail->db_txn, 0)));

  *trail_p = trail;
  return SVN_NO_ERROR;
}


static svn_error_t *
abort_trail (trail_t *trail,
             svn_fs_t *fs)
{
  struct undo *undo;

  /* Undo those changes which should only persist when the transaction
     succeeds.  */
  for (undo = trail->undo; undo; undo = undo->prev)
    if (undo->when & undo_on_failure)
      undo->func (undo->baton);

  SVN_ERR (DB_WRAP (fs, "aborting Berkeley DB transaction",
                    trail->db_txn->abort (trail->db_txn)));
 
  svn_pool_destroy (trail->pool);

  return SVN_NO_ERROR;
}


static svn_error_t *
commit_trail (trail_t *trail,
              svn_fs_t *fs)
{
  struct undo *undo;

  /* Undo those changes which should persist only while the
     transaction is active.  */
  for (undo = trail->undo; undo; undo = undo->prev)
    if (undo->when & undo_on_success)
      undo->func (undo->baton);

  /* According to the example in the Berkeley DB manual, txn_commit
     doesn't return DB_LOCK_DEADLOCK --- all deadlocks are reported
     earlier.  */
  SVN_ERR (DB_WRAP (fs, "committing Berkeley DB transaction",
                    trail->db_txn->commit (trail->db_txn, 0)));

  /* Do a checkpoint here, if enough has gone on.
     The checkpoint parameters below are pretty arbitrary.  Perhaps
     there should be an svn_fs_berkeley_mumble function to set them.  */
  SVN_ERR (DB_WRAP (fs, "checkpointing after Berkeley DB transaction",
                    fs->env->txn_checkpoint (fs->env, 1024, 5, 0)));

  /* We don't destroy the pool; we assume it contains stuff which will
     be useful beyond the transaction.  */

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs__retry_txn (svn_fs_t *fs,
                   svn_error_t *(*txn_body) (void *baton, trail_t *trail),
                   void *baton,
                   apr_pool_t *pool)
{
  for (;;)
    {
      trail_t *trail;
      svn_error_t *svn_err;
      
      SVN_ERR (begin_trail (&trail, fs, pool));

      /* Do the body of the transaction.  */
      svn_err = (*txn_body) (baton, trail);

      if (! svn_err)
        {
          /* The transaction succeeded!  Commit it.  */
          SVN_ERR (commit_trail (trail, fs));

          return SVN_NO_ERROR;
        }

      /* Is this a real error, or do we just need to retry?  */
      if (svn_err->apr_err != SVN_ERR_BERKELEY_DB
          || svn_err->src_err != DB_LOCK_DEADLOCK)
        {
          /* Ignore any error returns.  The first error is more valuable.  */
          abort_trail (trail, fs);
          return svn_err;
        }

      /* We deadlocked.  Abort the transaction, and try again.  */
      SVN_ERR (abort_trail (trail, fs));
    }
}


static void
record_undo (trail_t *trail,
             void (*func) (void *baton),
             void *baton,
             int when)
{
  struct undo *undo = apr_pcalloc (trail->pool, sizeof (*undo));

  undo->when = when;
  undo->func = func;
  undo->baton = baton;
  undo->prev = trail->undo;
  trail->undo = undo;
}
             

void
svn_fs__record_undo (trail_t *trail,
                     void (*func) (void *baton),
                     void *baton)
{
  record_undo (trail, func, baton, undo_on_failure);
}


void
svn_fs__record_completion (trail_t *trail,
                           void (*func) (void *baton),
                           void *baton)
{
  record_undo (trail, func, baton, undo_on_success | undo_on_failure);
}



/* 
 * local variables:
 * eval: (load-file "../../tools/dev/svn-dev.el")
 * end:
 */
