X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=src%2Flibmemcachedprotocol%2Fcache.c;h=39e2fc7d9ba5f02ce726e8dab6fcbe558e9387d0;hb=aeac01630eed825d8a624e7fd7c107d47bb2e40c;hp=c68cc254db09c96a85348b32814777ac735ef4dd;hpb=5bb6f975322d3da0caf082b8d890132194d0a4ea;p=awesomized%2Flibmemcached diff --git a/src/libmemcachedprotocol/cache.c b/src/libmemcachedprotocol/cache.c index c68cc254..39e2fc7d 100644 --- a/src/libmemcachedprotocol/cache.c +++ b/src/libmemcachedprotocol/cache.c @@ -1,189 +1,188 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Libmemcached library - * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * The names of its contributors may not be used to endorse or - * promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + +--------------------------------------------------------------------+ + | libmemcached - C/C++ Client Library for memcached | + +--------------------------------------------------------------------+ + | Redistribution and use in source and binary forms, with or without | + | modification, are permitted under the terms of the BSD license. | + | You should have received a copy of the license in a bundled file | + | named LICENSE; in case you did not receive a copy you can review | + | the terms online at: https://opensource.org/licenses/BSD-3-Clause | + +--------------------------------------------------------------------+ + | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ | + | Copyright (c) 2020 Michael Wallner | + +--------------------------------------------------------------------+ +*/ + #include "mem_config.h" #include #include #include -#ifndef NDEBUG -#include -#endif - #include "libmemcachedprotocol/common.h" -#ifndef NDEBUG -const uint64_t redzone_pattern = 0xdeadbeefcafebabe; -int cache_error = 0; -#endif +#ifndef HAVE_UMEM_H -const size_t initial_pool_size = 64; +# ifdef _MSC_VER +typedef SECURITY_ATTRIBUTES pthread_mutexattr_t; -cache_t* cache_create(const char *name, size_t bufsize, size_t align, - cache_constructor_t* constructor, - cache_destructor_t* destructor) { - cache_t* ret = calloc(1, sizeof(cache_t)); - size_t name_length= strlen(name); - char* nm= calloc(1, (sizeof(char) * name_length) +1); - memcpy(nm, name, name_length); - void** ptr = calloc(initial_pool_size, bufsize); - if (ret == NULL || nm == NULL || ptr == NULL || - pthread_mutex_init(&ret->mutex, NULL) == -1) { - free(ret); - free(nm); - free(ptr); - return NULL; +static inline int pthread_mutex_init(pthread_mutex_t *m, pthread_mutexattr_t *a) { + *m = CreateMutexA(a, FALSE, NULL); + return !*m; +} +static inline int pthread_mutex_destroy(pthread_mutex_t *m) { + return !CloseHandle(*m); +} +static inline int pthread_mutex_lock(pthread_mutex_t *m) { + if (WaitForSingleObject(*m, INFINITE)) { + return 0; } + return GetLastError(); +} +static inline int pthread_mutex_unlock(pthread_mutex_t *m) { + return !ReleaseMutex(*m); +} +# endif - ret->name = nm; - ret->ptr = ptr; - ret->freetotal = initial_pool_size; - ret->constructor = constructor; - ret->destructor = destructor; +# ifndef NDEBUG +# include -#ifndef NDEBUG - ret->bufsize = bufsize + 2 * sizeof(redzone_pattern); -#else - ret->bufsize = bufsize; -#endif +const uint64_t redzone_pattern = 0xdeadbeefcafebabe; +int cache_error = 0; - (void)align; +# endif - return ret; +const size_t initial_pool_size = 64; + +cache_t *cache_create(const char *name, size_t bufsize, size_t align, + cache_constructor_t *constructor, cache_destructor_t *destructor) { + cache_t *ret = calloc(1, sizeof(cache_t)); + size_t name_length = strlen(name); + char *nm = calloc(1, (sizeof(char) * name_length) + 1); + memcpy(nm, name, name_length); + void **ptr = calloc(initial_pool_size, bufsize); + if (ret == NULL || nm == NULL || ptr == NULL || pthread_mutex_init(&ret->mutex, NULL) == -1) { + free(ret); + free(nm); + free(ptr); + return NULL; + } + + ret->name = nm; + ret->ptr = ptr; + ret->freetotal = initial_pool_size; + ret->constructor = constructor; + ret->destructor = destructor; + +# ifndef NDEBUG + ret->bufsize = bufsize + 2 * sizeof(redzone_pattern); +# else + ret->bufsize = bufsize; +# endif + + (void) align; + + return ret; } -static inline void* get_object(void *ptr) { -#ifndef NDEBUG - uint64_t *pre = ptr; - return pre + 1; -#else - return ptr; -#endif +static inline void *get_object(void *ptr) { +# ifndef NDEBUG + uint64_t *pre = ptr; + return pre + 1; +# else + return ptr; +# endif } void cache_destroy(cache_t *cache) { - while (cache->freecurr > 0) { - void *ptr = cache->ptr[--cache->freecurr]; - if (cache->destructor) { - cache->destructor(get_object(ptr), NULL); - } - free(ptr); + while (cache->freecurr > 0) { + void *ptr = cache->ptr[--cache->freecurr]; + if (cache->destructor) { + cache->destructor(get_object(ptr), NULL); } - free(cache->name); - free(cache->ptr); - pthread_mutex_destroy(&cache->mutex); + free(ptr); + } + free(cache->name); + free(cache->ptr); + pthread_mutex_destroy(&cache->mutex); } -void* cache_alloc(cache_t *cache) { - void *ret; - void *object; - pthread_mutex_lock(&cache->mutex); - if (cache->freecurr > 0) { - ret = cache->ptr[--cache->freecurr]; - object = get_object(ret); - } else { - object = ret = malloc(cache->bufsize); - if (ret != NULL) { - object = get_object(ret); - - if (cache->constructor != NULL && - cache->constructor(object, NULL, 0) != 0) { - free(ret); - object = NULL; - } - } - } - pthread_mutex_unlock(&cache->mutex); - -#ifndef NDEBUG - if (object != NULL) { - /* add a simple form of buffer-check */ - uint64_t *pre = ret; - *pre = redzone_pattern; - ret = pre+1; - memcpy(((char*)ret) + cache->bufsize - (2 * sizeof(redzone_pattern)), - &redzone_pattern, sizeof(redzone_pattern)); +void *cache_alloc(cache_t *cache) { + void *ret; + void *object; + pthread_mutex_lock(&cache->mutex); + if (cache->freecurr > 0) { + ret = cache->ptr[--cache->freecurr]; + object = get_object(ret); + } else { + object = ret = malloc(cache->bufsize); + if (ret) { + object = get_object(ret); + + if (cache->constructor && cache->constructor(object, NULL, 0)) { + free(ret); + object = NULL; + } } -#endif - - return object; + } + pthread_mutex_unlock(&cache->mutex); + +# ifndef NDEBUG + if (object) { + /* add a simple form of buffer-check */ + uint64_t *pre = ret; + *pre = redzone_pattern; + ret = pre + 1; + memcpy(((char *) ret) + cache->bufsize - (2 * sizeof(redzone_pattern)), &redzone_pattern, + sizeof(redzone_pattern)); + } +# endif + + return object; } void cache_free(cache_t *cache, void *ptr) { - pthread_mutex_lock(&cache->mutex); - -#ifndef NDEBUG - /* validate redzone... */ - if (memcmp(((char*)ptr) + cache->bufsize - (2 * sizeof(redzone_pattern)), - &redzone_pattern, sizeof(redzone_pattern)) != 0) { - raise(SIGABRT); - cache_error = 1; - pthread_mutex_unlock(&cache->mutex); - return; - } - uint64_t *pre = ptr; - --pre; - if (*pre != redzone_pattern) { - raise(SIGABRT); - cache_error = -1; - pthread_mutex_unlock(&cache->mutex); - return; - } - ptr = pre; -#endif - if (cache->freecurr < cache->freetotal) { - cache->ptr[cache->freecurr++] = ptr; + pthread_mutex_lock(&cache->mutex); + +# ifndef NDEBUG + /* validate redzone... */ + if (memcmp(((char *) ptr) + cache->bufsize - (2 * sizeof(redzone_pattern)), &redzone_pattern, + sizeof(redzone_pattern)) +) + { + raise(SIGABRT); + cache_error = 1; + pthread_mutex_unlock(&cache->mutex); + return; + } + uint64_t *pre = ptr; + --pre; + if (*pre != redzone_pattern) { + raise(SIGABRT); + cache_error = -1; + pthread_mutex_unlock(&cache->mutex); + return; + } + ptr = pre; +# endif + if (cache->freecurr < cache->freetotal) { + cache->ptr[cache->freecurr++] = ptr; + } else { + /* try to enlarge free connections array */ + size_t newtotal = cache->freetotal * 2; + void **new_free = realloc(cache->ptr, sizeof(char *) * newtotal); + if (new_free) { + cache->freetotal = newtotal; + cache->ptr = new_free; + cache->ptr[cache->freecurr++] = ptr; } else { - /* try to enlarge free connections array */ - size_t newtotal = cache->freetotal * 2; - void **new_free = realloc(cache->ptr, sizeof(char *) * newtotal); - if (new_free) { - cache->freetotal = newtotal; - cache->ptr = new_free; - cache->ptr[cache->freecurr++] = ptr; - } else { - if (cache->destructor) { - cache->destructor(ptr, NULL); - } - free(ptr); - - } + if (cache->destructor) { + cache->destructor(ptr, NULL); + } + free(ptr); } - pthread_mutex_unlock(&cache->mutex); + } + pthread_mutex_unlock(&cache->mutex); } +#endif // HAVE_UMEM_H