示例#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);
}
示例#2
0
/**
 * \brief get content of given tile
 * 
 * fills the mapcache_tile::data of the given tile with content stored on the couchbase server
 * \private \memberof mapcache_cache_couchbase
 * \sa mapcache_cache::tile_get()
 */
static int _mapcache_cache_couchbase_get(mapcache_context *ctx, mapcache_tile *tile) {
   char *key[1];
   size_t keySize[1];
   libcouchbase_t *instance;
   libcouchbase_error_t error;
   getStruct_t request;

   key[0] = mapcache_util_get_tile_key(ctx, tile, NULL, " \r\n\t\f\e\a\b", "#");
   if(GC_HAS_ERROR(ctx)) {
      return MAPCACHE_FAILURE;
   }
   
   keySize[0] = strlen(key[0]);

   tile->encoded_data = mapcache_buffer_create(0, ctx->pool);

   libcouchbase_time_t expires = 86400;
   if(tile->tileset->auto_expire)
      expires = tile->tileset->auto_expire;

   instance = _couchbase_get_connection(ctx, tile);
   if (GC_HAS_ERROR(ctx)) {
      return MAPCACHE_FAILURE;
   }

   request.tileBuffer = tile->encoded_data;
   error = libcouchbase_mget(*instance, &request, 1, (const void * const*)key, keySize, &expires);
   if (error != LIBCOUCHBASE_SUCCESS) {
      ctx->set_error(ctx, 500, "couchbase cache returned error on mget %s", libcouchbase_strerror(*instance, error));
      _couchbase_invalidate_connection(tile, instance);
      return MAPCACHE_FAILURE;
   }
   
   libcouchbase_wait(*instance);

   if(request.error != LIBCOUCHBASE_SUCCESS) {
       _couchbase_release_connection(tile, instance);
       return MAPCACHE_CACHE_MISS;
   }

   if (tile->encoded_data->size == 0) {
      _couchbase_release_connection(tile, instance);
      ctx->set_error(ctx, 500, "couchbase cache returned 0-length data for tile %d %d %d", tile->x, tile->y, tile->z);
      return MAPCACHE_FAILURE;
   }
   
   apr_time_t now = apr_time_now();
   tile->mtime = now;

   _couchbase_release_connection(tile, instance);
   return MAPCACHE_SUCCESS;
}
示例#3
0
static int _mapcache_cache_couchbase_has_tile(mapcache_context *ctx, mapcache_tile *tile) {
   char *key[1];
   libcouchbase_t *instance;
   libcouchbase_error_t error;
   size_t keySize[1];
   getStruct_t request;

   key[0] = mapcache_util_get_tile_key(ctx, tile, NULL, " \r\n\t\f\e\a\b", "#");
   if(GC_HAS_ERROR(ctx)) {
      return MAPCACHE_FALSE;
   }

   keySize[0] = strlen(key[0]);

   instance = _couchbase_get_connection(ctx, tile);
   request.tileBuffer = 0;
   request.error = LIBCOUCHBASE_KEY_ENOENT;
   error = libcouchbase_mget(*instance, &request, 1, (const void * const*)key, keySize, 0);
   if (error != LIBCOUCHBASE_SUCCESS) {
      ctx->set_error(ctx, 500, "couchbase: failed to get key %s: %s", key, libcouchbase_strerror(*instance, error));
      _couchbase_invalidate_connection(tile, instance);
      return MAPCACHE_FALSE;
   }
   
   libcouchbase_wait(*instance);

   error = request.error;
   if (error != LIBCOUCHBASE_SUCCESS) {
      ctx->set_error(ctx, 500, "couchbase: failed to get key %s: %s", key, libcouchbase_strerror(*instance, error));
      _couchbase_invalidate_connection(tile, instance);
      return MAPCACHE_FALSE;
   }

   _couchbase_release_connection(tile, instance);
   return MAPCACHE_TRUE;
}