Esempio n. 1
0
static void reproduce_double_free_error(void)
{
    libcouchbase_error_t err;
    struct rvbuf rv;
    const char *key = "test_compare_and_swap_async_", *val = "{\"bar\" => 1}";
    libcouchbase_size_t nkey = strlen(key), nval = strlen(val);

    /* prefill the bucket */
    (void)libcouchbase_set_storage_callback(session, store_callback1);
    err = libcouchbase_store(session, &rv, LIBCOUCHBASE_SET, key, nkey, val, nval, 0, 0, 0);
    assert(err == LIBCOUCHBASE_SUCCESS);
    io->run_event_loop(io);
    assert(rv.error == LIBCOUCHBASE_SUCCESS);

    /* run exercise
     *
     * 1. get the value and its cas
     * 2. atomic set new value using old cas
     */
    (void)libcouchbase_set_storage_callback(session, store_callback2);
    (void)libcouchbase_set_get_callback(session, get_callback);
    err = libcouchbase_mget(session, &rv, 1, (const void * const *)&key, &nkey, NULL);
    assert(err == LIBCOUCHBASE_SUCCESS);
    rv.cas1 = rv.cas2 = 0;
    io->run_event_loop(io);
    assert(rv.error == LIBCOUCHBASE_SUCCESS);
    assert(rv.cas1 > 0);
    assert(rv.cas2 > 0);
    assert(rv.cas1 != rv.cas2);
}
Esempio n. 2
0
static void get_callback(libcouchbase_t instance,
                         const void *cookie,
                         libcouchbase_error_t error,
                         const void *key, libcouchbase_size_t nkey,
                         const void *bytes, libcouchbase_size_t nbytes,
                         libcouchbase_uint32_t flags, libcouchbase_cas_t cas)
{
    struct rvbuf *rv = (struct rvbuf *)cookie;
    const char *val = "{\"bar\"=>1, \"baz\"=>2}";
    libcouchbase_size_t nval = strlen(val);
    libcouchbase_error_t err;

    rv->error = error;
    rv->cas1 = cas;
    err = libcouchbase_store(session, rv, LIBCOUCHBASE_SET, key, nkey, val, nval, 0, 0, cas);
    assert(err == LIBCOUCHBASE_SUCCESS);

    (void)instance;
    (void)bytes;
    (void)nbytes;
    (void)flags;
}
Esempio n. 3
0
/**
 * \brief push tile data to couchbase
 * 
 * writes the content of mapcache_tile::data to the configured couchbased instance(s)
 * \private \memberof mapcache_cache_couchbase
 * \sa mapcache_cache::tile_set()
 */
static void _mapcache_cache_couchbase_set(mapcache_context *ctx, mapcache_tile *tile) {
   char *key;
   libcouchbase_t *instance;
   libcouchbase_error_t error;
   const int max_retries = 3;
   int retries = max_retries;
   apr_interval_time_t delay;

   /* set expiration to one day if not configured */
   libcouchbase_time_t expires = 86400;
   if(tile->tileset->auto_expire)
      expires = tile->tileset->auto_expire;

   mapcache_cache_couchbase *cache = (mapcache_cache_couchbase*)tile->tileset->cache;
   key = mapcache_util_get_tile_key(ctx, tile, NULL, " \r\n\t\f\e\a\b", "#");
   GC_CHECK_ERROR(ctx);
   
   if(!tile->encoded_data) {
      tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format);
      GC_CHECK_ERROR(ctx);
   }
   
   instance = _couchbase_get_connection(ctx, tile);
   GC_CHECK_ERROR(ctx);

   do
   {
      error = libcouchbase_store(*instance, &error, LIBCOUCHBASE_SET, key, strlen(key), tile->encoded_data->buf, tile->encoded_data->size, 0, expires, 0);
      if (error != LIBCOUCHBASE_SUCCESS) {
          _couchbase_release_connection(tile, instance);
          ctx->set_error(ctx, 500, "failed to store tile %d %d %d to couchbase cache %s due to eror %s.",
                         tile->x, tile->y, tile->z, cache->cache.name, libcouchbase_strerror(*instance, error));
          return;
      }
   
      libcouchbase_wait(*instance);

      if (error == LIBCOUCHBASE_ETMPFAIL) {
          if (retries > 0) {
              delay = 100000 * (1 << (max_retries - retries));	// Do an exponential back off of starting at 100 milliseconds
              apr_sleep(delay);
          }
          else {
              _couchbase_release_connection(tile, instance);
              ctx->set_error(ctx, 500, "failed to store tile %d %d %d to couchbase cache %s due to %s. Maximum number of retries used.",
                             tile->x, tile->y, tile->z, cache->cache.name, libcouchbase_strerror(*instance, error));
              return;
          }

          --retries;
      }

      else if (error != LIBCOUCHBASE_SUCCESS) {
          _couchbase_release_connection(tile, instance);
          ctx->set_error(ctx, 500, "failed to store tile %d %d %d to couchbase cache %s due to error %s.",
                         tile->x, tile->y, tile->z, cache->cache.name, libcouchbase_strerror(*instance, error));
          return;
      }
   }
   while (error == LIBCOUCHBASE_ETMPFAIL);

   _couchbase_release_connection(tile, instance);
}