From c204651e1ee8185224ccc78bd68801ab43740844 Mon Sep 17 00:00:00 2001 From: Trond Norbye Date: Sat, 26 Sep 2009 09:47:01 +0200 Subject: [PATCH] RFE: It should be possible to set behavior flags on a pool --- docs/Makefile.am | 8 ++++ docs/memcached_pool.pod | 15 +++++- libmemcached/memcached_pool.h | 5 ++ libmemcachedutil/memcached_pool.c | 76 +++++++++++++++++++++++++++++++ tests/function.c | 23 ++++++++++ 5 files changed, 126 insertions(+), 1 deletion(-) diff --git a/docs/Makefile.am b/docs/Makefile.am index 7972cc98..772b0344 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -107,6 +107,8 @@ man_MANS = libmemcached.3\ 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 \ @@ -327,6 +329,12 @@ memcached_get_user_data.3: memcached_user_data.pod 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 diff --git a/docs/memcached_pool.pod b/docs/memcached_pool.pod index 2b464ac2..ac85d3b9 100644 --- a/docs/memcached_pool.pod +++ b/docs/memcached_pool.pod @@ -18,6 +18,12 @@ C Client Library for memcached (libmemcachedutil, -lmemcachedutil) 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 @@ -46,6 +52,10 @@ to exceed the maximum size. 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 @@ -61,6 +71,9 @@ from the pool (or NULL if an allocation cannot be satisfied). 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: @@ -72,6 +85,6 @@ Trond Norbye, Etrond.norbye@sun.comE =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 diff --git a/libmemcached/memcached_pool.h b/libmemcached/memcached_pool.h index 7efe65e9..03fc0e3a 100644 --- a/libmemcached/memcached_pool.h +++ b/libmemcached/memcached_pool.h @@ -31,6 +31,11 @@ LIBMEMCACHED_API 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 diff --git a/libmemcachedutil/memcached_pool.c b/libmemcachedutil/memcached_pool.c index 708b7ce2..afc2fee3 100644 --- a/libmemcachedutil/memcached_pool.c +++ b/libmemcachedutil/memcached_pool.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */ #include "libmemcached/common.h" #include "libmemcached/memcached_pool.h" @@ -13,6 +14,7 @@ struct memcached_pool_st int firstfree; uint32_t size; uint32_t current_size; + char* version; }; static memcached_return mutex_enter(pthread_mutex_t *mutex) @@ -158,6 +160,18 @@ memcached_return memcached_pool_push(memcached_pool_st* pool, 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) @@ -166,5 +180,67 @@ memcached_return memcached_pool_push(memcached_pool_st* pool, 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); } diff --git a/tests/function.c b/tests/function.c index 41807771..1dce9ff8 100644 --- a/tests/function.c +++ b/tests/function.c @@ -3664,6 +3664,29 @@ static test_return connection_pool_test(memcached_st *memc) 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; } -- 2.30.2