X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Futil%2Fpool.c;h=fd3f6ffea2c64f76c7db46c8efe9ea26703227d0;hb=0ef2080bdbaafe7e3397530ac69ef4081f4f513e;hp=012d550f245f67f69112d4b4d42a6afd27684940;hpb=55b5455291498ef63c1c34976552d58708a74732;p=awesomized%2Flibmemcached diff --git a/libmemcached/util/pool.c b/libmemcached/util/pool.c index 012d550f..fd3f6ffe 100644 --- a/libmemcached/util/pool.c +++ b/libmemcached/util/pool.c @@ -1,3 +1,14 @@ +/* LibMemcached + * Copyright (C) 2010 Brian Aker + * All rights reserved. + * + * Use and distribution licensed under the BSD license. See + * the COPYING file in the parent directory for full text. + * + * Summary: connects to a host, and makes sure it is alive. + * + */ + /* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */ #include "libmemcached/common.h" #include "libmemcached/memcached_util.h" @@ -14,6 +25,7 @@ struct memcached_pool_st int firstfree; uint32_t size; uint32_t current_size; + bool _owns_master; char *version; }; @@ -57,31 +69,39 @@ static int grow_pool(memcached_pool_st* pool) pool->mmc[++pool->firstfree] = obj; pool->current_size++; - return 0; + return EXIT_SUCCESS; } -memcached_pool_st *memcached_pool_create(memcached_st* mmc, - uint32_t initial, uint32_t max) +static inline memcached_pool_st *_pool_create(memcached_st* mmc, uint32_t initial, uint32_t max) { - memcached_pool_st* ret = NULL; - memcached_pool_st object = { .mutex = PTHREAD_MUTEX_INITIALIZER, - .cond = PTHREAD_COND_INITIALIZER, - .master = mmc, - .mmc = calloc(max, sizeof(memcached_st*)), - .firstfree = -1, - .size = max, - .current_size = 0 }; + memcached_pool_st* ret= NULL; + + if (! initial || ! max || initial > max) + { + errno= EINVAL; + return NULL; + } + + memcached_pool_st object= { .mutex = PTHREAD_MUTEX_INITIALIZER, + .cond= PTHREAD_COND_INITIALIZER, + .master= mmc, + .mmc= calloc(max, sizeof(memcached_st*)), + .firstfree= -1, + .size= max, + .current_size= 0, + ._owns_master= false}; if (object.mmc != NULL) { - ret= calloc(1, sizeof(*ret)); + ret= (memcached_pool_st*)calloc(1, sizeof(memcached_pool_st)); if (ret == NULL) { free(object.mmc); + errno= ENOMEM; // Set this for the failed calloc return NULL; } - *ret = object; + *ret= object; /* Try to create the initial size of the pool. An allocation failure at @@ -97,9 +117,39 @@ memcached_pool_st *memcached_pool_create(memcached_st* mmc, return ret; } +memcached_pool_st *memcached_pool_create(memcached_st* mmc, uint32_t initial, uint32_t max) +{ + return _pool_create(mmc, initial, max); +} + +memcached_pool_st * memcached_pool(const char *option_string, size_t option_string_length) +{ + memcached_pool_st *self; + memcached_st *memc= memcached_create_with_options(option_string, option_string_length); + + if (! memc) + return NULL; + + self= memcached_pool_create(memc, memc->configure.initial_pool_size, memc->configure.max_pool_size); + if (! self) + { + memcached_free(memc); + errno= ENOMEM; + return NULL; + } + errno= 0; + + self->_owns_master= true; + + return self; +} + memcached_st* memcached_pool_destroy(memcached_pool_st* pool) { - memcached_st *ret = pool->master; + if (! pool) + return NULL; + + memcached_st *ret= pool->master; for (int xx= 0; xx <= pool->firstfree; ++xx) { @@ -111,6 +161,11 @@ memcached_st* memcached_pool_destroy(memcached_pool_st* pool) pthread_mutex_destroy(&pool->mutex); pthread_cond_destroy(&pool->cond); free(pool->mmc); + if (pool->_owns_master) + { + memcached_free(pool->master); + ret= NULL; + } free(pool); return ret; @@ -120,14 +175,24 @@ memcached_st* memcached_pool_pop(memcached_pool_st* pool, bool block, memcached_return_t *rc) { + if (! pool || ! rc) + { + errno= EINVAL; + return NULL; + } + memcached_st *ret= NULL; if ((*rc= mutex_enter(&pool->mutex)) != MEMCACHED_SUCCESS) + { return NULL; + } do { if (pool->firstfree > -1) + { ret= pool->mmc[pool->firstfree--]; + } else if (pool->current_size == pool->size) { if (!block) @@ -138,9 +203,9 @@ memcached_st* memcached_pool_pop(memcached_pool_st* pool, if (pthread_cond_wait(&pool->cond, &pool->mutex) == -1) { - int err = errno; + int err= errno; mutex_exit(&pool->mutex); - errno = err; + errno= err; *rc= MEMCACHED_ERRNO; return NULL; } @@ -161,6 +226,9 @@ memcached_st* memcached_pool_pop(memcached_pool_st* pool, memcached_return_t memcached_pool_push(memcached_pool_st* pool, memcached_st *mmc) { + if (! pool) + return MEMCACHED_INVALID_ARGUMENTS; + memcached_return_t rc= mutex_enter(&pool->mutex); if (rc != MEMCACHED_SUCCESS) @@ -198,6 +266,8 @@ memcached_return_t memcached_pool_behavior_set(memcached_pool_st *pool, memcached_behavior_t flag, uint64_t data) { + if (! pool) + return MEMCACHED_INVALID_ARGUMENTS; memcached_return_t rc= mutex_enter(&pool->mutex); if (rc != MEMCACHED_SUCCESS) @@ -218,11 +288,14 @@ memcached_return_t memcached_pool_behavior_set(memcached_pool_st *pool, { 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 @@ -244,8 +317,10 @@ memcached_return_t memcached_pool_behavior_get(memcached_pool_st *pool, memcached_behavior_t flag, uint64_t *value) { - memcached_return_t rc= mutex_enter(&pool->mutex); + if (! pool) + return MEMCACHED_INVALID_ARGUMENTS; + memcached_return_t rc= mutex_enter(&pool->mutex); if (rc != MEMCACHED_SUCCESS) { return rc;