if BUILD_LIBMEMCACHEDUTIL
man_MANS+= libmemcachedutil.3 \
+ memcached_pool_behavior_set.3 \
+ memcached_pool_behavior_get.3 \
memcached_pool_create.3 \
memcached_pool_destroy.3 \
memcached_pool_push.3 \
memcached_set_user_data.3: memcached_user_data.pod
${POD2MAN} -c "libmemcached" -r "" -s 3 ${top_srcdir}/docs/memcached_user_data.pod > memcached_set_user_data.3
+memcached_pool_behavior_get.3: memcached_pool.pod
+ ${POD2MAN} -c "libmemcachedutil" -r "" -s 3 ${top_srcdir}/docs/memcached_pool.pod > memcached_pool_behavior_get.3
+
+memcached_pool_behavior_set.3: memcached_pool.pod
+ ${POD2MAN} -c "libmemcachedutil" -r "" -s 3 ${top_srcdir}/docs/memcached_pool.pod > memcached_pool_behavior_set.3
+
memcached_pool_create.3: memcached_pool.pod
${POD2MAN} -c "libmemcachedutil" -r "" -s 3 ${top_srcdir}/docs/memcached_pool.pod > memcached_pool_create.3
memcached_st *memcached_create (memcached_st *ptr);
+ memcached_return memcached_pool_behavior_set(memcached_pool_st *pool,
+ memcached_behavior flag,
+ uint64_t data)
+ memcached_return memcached_pool_behavior_get(memcached_pool_st *pool,
+ memcached_behavior flag,
+ uint64_t *value)
=head1 DESCRIPTION
memcached_pool_push() is used to return a connection structure back to the pool.
+memcached_pool_behavior_set() and memcached_pool_behagior_get() is
+used to get/set behavior flags on all connections in the pool.
+
+
=head1 RETURN
memcached_pool_create() returns a pointer to the newly created
memcached_pool_push() returns MEMCACHED_SUCCESS upon success.
+memcached_pool_behavior_get() and memcached_pool_behavior_get()
+returns MEMCACHED_SUCCESS upon success.
+
=head1 HOME
To find out more information please check:
=head1 SEE ALSO
-memcached(1) libmemcached(3) memcached_create(3) memcached_free(3) libmemcachedutil(3)
+memcached(1) libmemcached(3) memcached_create(3) memcached_free(3) libmemcachedutil(3) memcached_behavior_get(3) memcached_behavior_set(3)
=cut
memcached_return memcached_pool_push(memcached_pool_st* pool,
memcached_st* mmc);
+LIBMEMCACHED_API
+memcached_return memcached_pool_behavior_set(memcached_pool_st *ptr, memcached_behavior flag, uint64_t data);
+LIBMEMCACHED_API
+memcached_return memcached_pool_behavior_get(memcached_pool_st *ptr, memcached_behavior flag, uint64_t *value);
+
#ifdef __cplusplus
}
#endif
+/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
#include "libmemcached/common.h"
#include "libmemcached/memcached_pool.h"
int firstfree;
uint32_t size;
uint32_t current_size;
+ char* version;
};
static memcached_return mutex_enter(pthread_mutex_t *mutex)
if (rc != MEMCACHED_SUCCESS)
return rc;
+ char* version = memcached_get_user_data(mmc);
+ /* Someone updated the behavior on the object.. */
+ if (version != pool->version)
+ {
+ memcached_free(mmc);
+ memset(mmc, 0, sizeof(*mmc));
+ if (memcached_clone(mmc, pool->master) == NULL)
+ {
+ rc= MEMCACHED_SOME_ERRORS;
+ }
+ }
+
pool->mmc[++pool->firstfree]= mmc;
if (pool->firstfree == 0 && pool->current_size == pool->size)
pthread_cond_broadcast(&pool->cond);
}
+ memcached_return rval= mutex_exit(&pool->mutex);
+ if (rc == MEMCACHED_SOME_ERRORS)
+ return rc;
+
+ return rval;
+}
+
+
+memcached_return memcached_pool_behavior_set(memcached_pool_st *pool,
+ memcached_behavior flag,
+ uint64_t data)
+{
+
+ memcached_return rc= mutex_enter(&pool->mutex);
+ if (rc != MEMCACHED_SUCCESS)
+ return rc;
+
+ /* update the master */
+ rc= memcached_behavior_set(pool->master, flag, data);
+ if (rc != MEMCACHED_SUCCESS)
+ {
+ mutex_exit(&pool->mutex);
+ return rc;
+ }
+
+ ++pool->version;
+ memcached_set_user_data(pool->master, pool->version);
+ /* update the clones */
+ for (int xx= 0; xx <= pool->firstfree; ++xx)
+ {
+ rc= memcached_behavior_set(pool->mmc[xx], flag, data);
+ if (rc == MEMCACHED_SUCCESS)
+ memcached_set_user_data(pool->mmc[xx], pool->version);
+ else
+ {
+ memcached_free(pool->mmc[xx]);
+ memset(pool->mmc[xx], 0, sizeof(*pool->mmc[xx]));
+ if (memcached_clone(pool->mmc[xx], pool->master) == NULL)
+ {
+ /* I'm not sure what to do in this case.. this would happen
+ if we fail to push the server list inside the client..
+ I should add a testcase for this, but I believe the following
+ would work, except that you would add a hole in the pool list..
+ in theory you could end up with an empty pool....
+ */
+ free(pool->mmc[xx]);
+ pool->mmc[xx]= NULL;
+ }
+ }
+ }
+
+ return mutex_exit(&pool->mutex);
+}
+
+memcached_return memcached_pool_behavior_get(memcached_pool_st *pool,
+ memcached_behavior flag,
+ uint64_t *value)
+{
+ memcached_return rc= mutex_enter(&pool->mutex);
+ if (rc != MEMCACHED_SUCCESS)
+ return rc;
+ *value= memcached_behavior_get(pool->master, flag);
return mutex_exit(&pool->mutex);
}
for (int x= 0; x < 10; ++x)
assert(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
+
+ /* verify that I can set behaviors on the pool when I don't have all
+ * of the connections in the pool. It should however be enabled
+ * when I push the item into the pool
+ */
+ mmc[0]= memcached_pool_pop(pool, false, &rc);
+ assert(mmc[0] != NULL);
+
+ rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ mmc[1]= memcached_pool_pop(pool, false, &rc);
+ assert(mmc[1] != NULL);
+
+ assert(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
+ assert(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
+ assert(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
+
+ mmc[0]= memcached_pool_pop(pool, false, &rc);
+ assert(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
+ assert(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
+
+
assert(memcached_pool_destroy(pool) == memc);
return TEST_SUCCESS;
}