Esempio n. 1
0
static svn_error_t *
svn_fs_bdb__close_internal(bdb_env_t *bdb)
{
  svn_error_t *err = SVN_NO_ERROR;

  if (--bdb->refcount != 0)
    {
      /* If the environment is panicked and automatic recovery is not
         enabled, return an appropriate error. */
#if !SVN_BDB_AUTO_RECOVER
      if (svn_atomic_read(&bdb->panic))
        err = svn_error_create(SVN_ERR_FS_BERKELEY_DB, NULL,
                                db_strerror(DB_RUNRECOVERY));
#endif
    }
  else
    {
      /* If the bdb cache has been set to NULL that means we are
         shutting down, and the pool that holds the bdb cache has
         already been destroyed, so accessing it here would be a Bad
         Thing (tm) */
      if (bdb_cache)
        apr_hash_set(bdb_cache, &bdb->key, sizeof bdb->key, NULL);
      err = bdb_close(bdb);
    }
  return svn_error_trace(err);
}
Esempio n. 2
0
/* Find a BDB environment in the cache.
   Return the environment's panic state in *PANICP.

   Note: You MUST acquire the cache mutex before calling this function.
*/
static bdb_env_t *
bdb_cache_get(const bdb_env_key_t *keyp, svn_boolean_t *panicp)
{
  bdb_env_t *bdb = apr_hash_get(bdb_cache, keyp, sizeof *keyp);
  if (bdb && bdb->env)
    {
      *panicp = !!svn_atomic_read(&bdb->panic);
#if SVN_BDB_VERSION_AT_LEAST(4,2)
      if (!*panicp)
        {
          u_int32_t flags;
          if (bdb->env->get_flags(bdb->env, &flags)
              || (flags & DB_PANIC_ENVIRONMENT))
            {
              /* Something is wrong with the environment. */
              svn_atomic_set(&bdb->panic, TRUE);
              *panicp = TRUE;
              bdb = NULL;
            }
        }
#endif /* at least bdb-4.2 */
    }
  else
    {
      *panicp = FALSE;
    }
  return bdb;
}
Esempio n. 3
0
svn_boolean_t
svn_fs_bdb__get_panic(bdb_env_baton_t *bdb_baton)
{
  /* An invalid baton is equivalent to a panicked environment; in both
     cases, database cleanups should be skipped. */
  if (!bdb_baton->bdb)
    return TRUE;

  assert(bdb_baton->env == bdb_baton->bdb->env);
  return !!svn_atomic_read(&bdb_baton->bdb->panic);
}
Esempio n. 4
0
svn_error_t *
svn_named_atomic__get(svn_named_atomic__t **atomic,
                      svn_atomic_namespace__t *ns,
                      const char *name,
                      svn_boolean_t auto_create)
{
  apr_uint32_t i, count;
  svn_error_t *error = SVN_NO_ERROR;
  apr_size_t len = strlen(name);

  /* Check parameters and make sure we return a NULL atomic
   * in case of failure.
   */
  *atomic = NULL;
  if (len > SVN_NAMED_ATOMIC__MAX_NAME_LENGTH)
    return svn_error_create(SVN_ERR_BAD_ATOMIC, 0,
                            _("Atomic's name is too long."));

  /* If no namespace has been provided, bail out.
   */
  if (ns == NULL || ns->data == NULL)
    return svn_error_create(SVN_ERR_BAD_ATOMIC, 0,
                            _("Namespace has not been initialized."));

  /* Optimistic lookup.
   * Because we never change the name of existing atomics and may only
   * append new ones, we can safely compare the name of existing ones
   * with the name that we are looking for.
   */
  for (i = 0, count = svn_atomic_read(&ns->min_used); i < count; ++i)
    if (strncmp(ns->data->atomics[i].name, name, len + 1) == 0)
      {
        return_atomic(atomic, ns, i);
        return SVN_NO_ERROR;
      }

  /* Try harder:
   * Serialize all lookup and insert the item, if necessary and allowed.
   */
  SVN_ERR(lock(&ns->mutex));

  /* We only need to check for new entries.
   */
  for (i = count; i < ns->data->count; ++i)
    if (strncmp(ns->data->atomics[i].name, name, len + 1) == 0)
      {
        return_atomic(atomic, ns, i);

        /* Update our cached number of complete entries. */
        svn_atomic_set(&ns->min_used, ns->data->count);

        return unlock(&ns->mutex, error);
      }

  /* Not found.  Append a new entry, if allowed & possible.
   */
  if (auto_create)
    {
      if (ns->data->count < MAX_ATOMIC_COUNT)
        {
          ns->data->atomics[ns->data->count].value = 0;
          memcpy(ns->data->atomics[ns->data->count].name,
                 name,
                 len+1);

          return_atomic(atomic, ns, ns->data->count);
          ++ns->data->count;
        }
        else
          error = svn_error_create(SVN_ERR_BAD_ATOMIC, 0,
                                  _("Out of slots for named atomic."));
    }

  /* We are mainly done here.  Let others continue their work.
   */
  SVN_ERR(unlock(&ns->mutex, error));

  /* Only now can we be sure that a full memory barrier has been set
   * and that the new entry has been written to memory in full.
   */
  svn_atomic_set(&ns->min_used, ns->data->count);

  return SVN_NO_ERROR;
}
Esempio n. 5
0
bool
OperationContext::isCancelledOperation()
{
  return bool(svn_atomic_read(&m_cancelOperation));
}