docs/memrm.1
docs/memslap.1
docs/memstat.1
+docs/memcached_set_memory_allocators.3
+docs/memcached_get_memory_allocators.3
libmemcached/.deps
libmemcached/.libs
libmemcached/Makefile
memdump.pod\
memcached_flush_buffers.pod\
memcached_analyze.pod\
- memcached_generate_hash_value.pod
+ memcached_generate_hash_value.pod\
+ memcached_memory_allocators.pod
man_MANS = libmemcached.3\
libmemcached_examples.3\
memcached_version.3\
memcached_flush_buffers.3\
memcached_dump.3\
- memcached_generate_hash_value.3
+ memcached_generate_hash_value.3\
+ memcached_set_memory_allocators.3\
+ memcached_get_memory_allocators.3
if BUILD_LIBMEMCACHEDUTIL
man_MANS+= libmemcachedutil.3 \
memcached_generate_hash_value.3: memcached_generate_hash_value.pod
@POD2MAN@ -c "libmemcached" -r "" -s 3 ${top_srcdir}/docs/memcached_generate_hash_value.pod > memcached_generate_hash_value.3
+memcached_get_memory_allocators.3: memcached_memory_allocators.pod
+ @POD2MAN@ -c "libmemcached" -r "" -s 3 ${top_srcdir}/docs/memcached_memory_allocators.pod > memcached_get_memory_allocators.3
+
+memcached_set_memory_allocators.3: memcached_memory_allocators.pod
+ @POD2MAN@ -c "libmemcached" -r "" -s 3 ${top_srcdir}/docs/memcached_memory_allocators.pod > memcached_set_memory_allocators.3
+
memcached_pool_create.3: memcached_pool.pod
@POD2MAN@ -c "libmemcachedutil" -r "" -s 3 ${top_srcdir}/docs/memcached_pool.pod > memcached_pool_create.3
podchecker $(top_srcdir)/docs/memflush.pod
podchecker $(top_srcdir)/docs/memcached_flush_buffers.pod
podchecker $(top_srcdir)/docs/memcached_pool.pod
+ podchecker $(top_srcdir)/docs/memcached_memory_allocators.pod
html-local:
pod2htmltree "/libmemcached" .
=item MEMCACHED_CALLBACK_MALLOC_FUNCTION
-This alllows yout to pass in a customized version of malloc that will be used instead of the builtin malloc(3) call.
-Your malloc must zero all memory.
-The prototype for this is:
-
-void *(*memcached_malloc_function)(memcached_st *ptr, const size_t size);
+DEPRECATED: use memcached_set_memory_allocators instead.
=item MEMCACHED_CALLBACK_REALLOC_FUNCTION
-This alllows yout to pass in a customized version of realloc that will be used instead of the builtin realloc(3) call.
-The prototype for this is:
-
-void *(*memcached_realloc_function)(memcached_st *ptr, void *mem, const size_t size);
+DEPRECATED: use memcached_set_memory_allocators instead.
=item MEMCACHED_CALLBACK_FREE_FUNCTION
-This alllows yout to pass in a customized version of realloc that will be used instead of the builtin free(3) call.
-The prototype for this is:
-
-typedef void (*memcached_free_function)(memcached_st *ptr, void *mem);
+DEPRECATED: use memcached_set_memory_allocators instead.
=item MEMCACHED_CALLBACK_GET_FAILURE
--- /dev/null
+=head1 NAME
+
+memcached_set_memory_allocators, memcached_get_memory_allocators
+
+=head1 LIBRARY
+
+C Client Library for memcached (libmemcached, -lmemcached)
+
+=head1 SYNOPSIS
+
+ #include <memcached.h>
+
+ memcached_return
+ memcached_set_memory_allocators(memcached_st *ptr,
+ memcached_malloc_function mem_malloc,
+ memcached_free_function mem_free,
+ memcached_realloc_function mem_realloc,
+ memcached_calloc_function mem_calloc);
+
+ void memcached_get_memory_allocators(memcached_st *ptr,
+ memcached_malloc_function *mem_malloc,
+ memcached_free_function *mem_free,
+ memcached_realloc_function *mem_realloc,
+ memcached_calloc_function *mem_calloc);
+
+ void *(*memcached_malloc_function)(memcached_st *ptr, const size_t size);
+ void *(*memcached_realloc_function)(memcached_st *ptr, void *mem,
+ const size_t size);
+ void (*memcached_free_function)(memcached_st *ptr, void *mem);
+ void *(*memcached_calloc_function)(memcached_st *ptr, size_t nelem,
+ const size_t elsize);
+
+
+=head1 DESCRIPTION
+
+libmemcached(3) allows you to specify your own memory allocators optimized
+for your application.
+
+memcached_set_memory_allocators() is used to set the memory allocators used
+by the memcached instance specified by ptr. Please note that you cannot
+override only one of the memory allocators, you have to specify a complete
+new set if you want to override one of them. All of the memory allocation
+functions should behave as specified in the C99 standard. Specify NULL as
+all functions to reset them to the default values.
+
+memcached_get_memory_allocators() is used to get the currently used memory
+allocators by a mamcached handle.
+
+=head1 RETURN
+
+memcached_set_memory_allocators() return MEMCACHED_SUCCESS upon success,
+and MEMCACHED_FAILURE if you don't pass a complete set of function pointers.
+
+=head1 HOME
+
+To find out more information please check:
+L<http://tangent.org/552/libmemcached.html>
+
+=head1 AUTHOR
+
+Trond Norbye, E<lt>trond.norbye@sun.comE<gt>
+
+=head1 SEE ALSO
+
+memcached(1) libmemcached(3)
+
+=cut
+
noinst_HEADERS = libmemcached_probes.h \
libmemcached_config.h \
memcached_io.h \
+ memcached_internal.h \
common.h \
memcached/protocol_binary.h @DTRACE_HEADER@
memcached_verbosity.c \
memcached_version.c \
murmur_hash.c \
- jenkins_hash.c
+ jenkins_hash.c \
+ memcached_allocators.c
if INCLUDE_HSIEH_SRC
libmemcached_la_SOURCES += hsieh_hash.c
{
memset(ptr, 0, sizeof(memcached_st));
}
+
+ memcached_set_memory_allocators(ptr, NULL, NULL, NULL, NULL);
+
result_ptr= memcached_result_create(ptr, &ptr->result);
WATCHPOINT_ASSERT(result_ptr);
ptr->poll_timeout= MEMCACHED_DEFAULT_TIMEOUT;
ptr->on_cleanup(ptr);
if (ptr->continuum)
- {
- if (ptr->call_free)
- ptr->call_free(ptr, ptr->continuum);
- else
- free(ptr->continuum);
- }
+ ptr->call_free(ptr, ptr->continuum);
if (ptr->is_allocated)
- {
- if (ptr->call_free)
- ptr->call_free(ptr, ptr);
- else
- free(ptr);
- }
+ ptr->call_free(ptr, ptr);
else
memset(ptr, 0, sizeof(memcached_st));
}
memcached_free_function call_free;
memcached_malloc_function call_malloc;
memcached_realloc_function call_realloc;
+ memcached_calloc_function call_calloc;
memcached_trigger_key get_key_failure;
memcached_trigger_delete_key delete_trigger;
char prefix_key[MEMCACHED_PREFIX_KEY_MAX_SIZE];
memcached_return memcached_dump(memcached_st *ptr, memcached_dump_func *function, void *context, uint32_t number_of_callbacks);
+memcached_return memcached_set_memory_allocators(memcached_st *ptr,
+ memcached_malloc_function mem_malloc,
+ memcached_free_function mem_free,
+ memcached_realloc_function mem_realloc,
+ memcached_calloc_function mem_calloc);
+
+void memcached_get_memory_allocators(memcached_st *ptr,
+ memcached_malloc_function *mem_malloc,
+ memcached_free_function *mem_free,
+ memcached_realloc_function *mem_realloc,
+ memcached_calloc_function *mem_calloc);
+
#ifdef __cplusplus
}
#endif
#include <libmemcached/memcached_storage.h>
+#ifdef MEMCACHED_INTERNAL
+#include <libmemcached/memcached_internal.h>
+#endif
+
#endif /* __MEMCACHED_H__ */
--- /dev/null
+#include "common.h"
+
+void libmemcached_free(memcached_st *ptr __attribute__((unused)), void *mem)
+{
+ free(mem);
+}
+
+void *libmemcached_malloc(memcached_st *ptr __attribute__((unused)),
+ size_t size)
+{
+ return malloc(size);
+}
+
+void *libmemcached_realloc(memcached_st *ptr __attribute__((unused)),
+ void *mem, size_t size)
+{
+ return realloc(mem, size);
+}
+
+void *libmemcached_calloc(memcached_st *ptr __attribute__((unused)),
+ size_t nelem, size_t size)
+{
+ if (ptr->call_malloc != libmemcached_malloc)
+ {
+ void *ret = libmemcached_malloc(ptr, nelem * size);
+ if (ret != NULL)
+ memset(ret, 0, nelem * size);
+
+ return ret;
+ }
+
+ return calloc(nelem, size);
+}
+
+memcached_return memcached_set_memory_allocators(memcached_st *ptr,
+ memcached_malloc_function mem_malloc,
+ memcached_free_function mem_free,
+ memcached_realloc_function mem_realloc,
+ memcached_calloc_function mem_calloc)
+{
+ /* All should be set, or none should be set */
+ if (mem_malloc == NULL && mem_free == NULL && mem_realloc == NULL && mem_calloc == NULL)
+ {
+ ptr->call_malloc= libmemcached_malloc;
+ ptr->call_free= libmemcached_free;
+ ptr->call_realloc= libmemcached_realloc;
+ ptr->call_calloc= libmemcached_calloc;
+ }
+ else if (mem_malloc == NULL || mem_free == NULL || mem_realloc == NULL || mem_calloc == NULL)
+ return MEMCACHED_FAILURE;
+ else
+ {
+ ptr->call_malloc= mem_malloc;
+ ptr->call_free= mem_free;
+ ptr->call_realloc= mem_realloc;
+ ptr->call_calloc= mem_calloc;
+ }
+
+ return MEMCACHED_SUCCESS;
+}
+
+void memcached_get_memory_allocators(memcached_st *ptr,
+ memcached_malloc_function *mem_malloc,
+ memcached_free_function *mem_free,
+ memcached_realloc_function *mem_realloc,
+ memcached_calloc_function *mem_calloc)
+{
+ *mem_malloc= ptr->call_malloc;
+ *mem_free= ptr->call_free;
+ *mem_realloc= ptr->call_realloc;
+ *mem_calloc= ptr->call_calloc;
+}
*error= MEMCACHED_SUCCESS;
server_count= memcached_server_count(memc);
- result= (memcached_analysis_st*)calloc(1, sizeof(memcached_analysis_st)
- * (memc->number_of_hosts));
+ result= (memcached_analysis_st*)calloc(memc->number_of_hosts,
+ sizeof(memcached_analysis_st));
+
if (!result)
{
*error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
servers[x].address_info= NULL;
}
- if (ptr && ptr->call_free)
+ if (ptr)
ptr->call_free(ptr, servers);
else
free(servers);
{
memcached_continuum_item_st *new_ptr;
- if (ptr->call_realloc)
- new_ptr= (memcached_continuum_item_st *)ptr->call_realloc(ptr, ptr->continuum,
- sizeof(memcached_continuum_item_st) * (live_servers + MEMCACHED_CONTINUUM_ADDITION) * points_per_server);
- else
- new_ptr= (memcached_continuum_item_st *)realloc(ptr->continuum,
- sizeof(memcached_continuum_item_st) * (live_servers + MEMCACHED_CONTINUUM_ADDITION) * points_per_server);
+ new_ptr= ptr->call_realloc(ptr, ptr->continuum,
+ sizeof(memcached_continuum_item_st) * (live_servers + MEMCACHED_CONTINUUM_ADDITION) * points_per_server);
if (new_ptr == 0)
return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
return MEMCACHED_SUCCESS;
count= list[0].count;
- if (ptr->call_realloc)
- new_host_list=
- (memcached_server_st *)ptr->call_realloc(ptr, ptr->hosts,
- sizeof(memcached_server_st) * (count + ptr->number_of_hosts));
- else
- new_host_list=
- (memcached_server_st *)realloc(ptr->hosts,
- sizeof(memcached_server_st) * (count + ptr->number_of_hosts));
+ new_host_list= ptr->call_realloc(ptr, ptr->hosts,
+ sizeof(memcached_server_st) * (count + ptr->number_of_hosts));
if (!new_host_list)
return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
|| ( (type == MEMCACHED_CONNECTION_UDP) && !(ptr->flags & MEM_USE_UDP) ) )
return MEMCACHED_INVALID_HOST_PROTOCOL;
- if (ptr->call_realloc)
- new_host_list= (memcached_server_st *)ptr->call_realloc(ptr, ptr->hosts,
- sizeof(memcached_server_st) * (ptr->number_of_hosts+1));
- else
- new_host_list= (memcached_server_st *)realloc(ptr->hosts,
- sizeof(memcached_server_st) * (ptr->number_of_hosts+1));
+ new_host_list= ptr->call_realloc(ptr, ptr->hosts,
+ sizeof(memcached_server_st) * (ptr->number_of_hosts+1));
+
if (new_host_list == NULL)
return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
--- /dev/null
+/*
+ * Summary: Internal functions used by the library. Not for public use!
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Trond Norbye
+ */
+
+#if !defined(MEMCACHED_INTERNAL_H) && defined(MEMCACHED_INTERNAL)
+#define MEMCACHED_INTERNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void libmemcached_free(memcached_st *ptr __attribute__((unused)), void *mem);
+void *libmemcached_malloc(memcached_st *ptr __attribute__((unused)),
+ const size_t size);
+void *libmemcached_realloc(memcached_st *ptr __attribute__((unused)),
+ void *mem, const size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MEMCACHED_INTERNAL_H */
memset(ptr, 0, sizeof(memcached_result_st));
else
{
- if (memc->call_malloc)
- ptr= (memcached_result_st *)memc->call_malloc(memc, sizeof(memcached_result_st));
- else
- ptr= (memcached_result_st *)calloc(1, sizeof(memcached_result_st));
+ ptr= memc->call_malloc(memc, sizeof(memcached_result_st));
if (ptr == NULL)
return NULL;
}
if (ptr->is_allocated)
- {
- if (ptr->root && ptr->root->call_free)
- ptr->root->call_free(ptr->root, ptr);
- else
- free(ptr);
- }
+ ptr->root->call_free(ptr->root, ptr);
else
memset(ptr, 0, sizeof(memcached_server_st));
}
return NULL;
}
- if (ptr->call_malloc)
- ret= ptr->call_malloc(ptr, length + 1);
- else
- ret= malloc(length + 1);
+ ret= ptr->call_malloc(ptr, length + 1);
memcpy(ret, buffer, length);
ret[length]= '\0';
return NULL;
}
- if (ptr->call_malloc)
- stats= (memcached_stat_st *)ptr->call_malloc(ptr, sizeof(memcached_stat_st)*(ptr->number_of_hosts));
- else
- stats= (memcached_stat_st *)calloc(1, sizeof(memcached_stat_st)*(ptr->number_of_hosts));
+ stats= ptr->call_calloc(ptr, ptr->number_of_hosts, sizeof(memcached_stat_st));
if (!stats)
{
char **list;
size_t length= sizeof(memcached_stat_keys);
- if (ptr->call_malloc)
- list= (char **)ptr->call_malloc(ptr, length);
- else
- list= (char **)calloc(1, length);
+ list= ptr->call_malloc(ptr, length);
if (!list)
{
return;
}
- if (ptr && ptr->call_free)
+ if (ptr)
ptr->call_free(ptr, stat);
else
free(stat);
if (new_size < need)
return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
- if (string->root->call_realloc)
- new_value= (char *)string->root->call_realloc(string->root, string->string, new_size);
- else
- new_value= (char *)realloc(string->string, new_size);
+ new_value= string->root->call_realloc(string->root, string->string, new_size);
if (new_value == NULL)
return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
memset(string, 0, sizeof(memcached_string_st));
else
{
- if (ptr->call_malloc)
- string= (memcached_string_st *)ptr->call_malloc(ptr, sizeof(memcached_string_st));
- else
- string= (memcached_string_st *)calloc(1, sizeof(memcached_string_st));
+ string= ptr->call_calloc(ptr, 1, sizeof(memcached_string_st));
if (string == NULL)
return NULL;
rc= memcached_string_check(string, initial_size);
if (rc != MEMCACHED_SUCCESS)
{
- if (ptr->call_free)
- ptr->call_free(ptr, string);
- else
- free(string);
-
+ ptr->call_free(ptr, string);
return NULL;
}
if (memcached_string_length(string) == 0)
return NULL;
- if (string->root->call_malloc)
- c_ptr= (char *)string->root->call_malloc(string->root, (memcached_string_length(string)+1) * sizeof(char));
- else
- c_ptr= (char *)malloc((memcached_string_length(string)+1) * sizeof(char));
+ c_ptr= string->root->call_malloc(string->root, (memcached_string_length(string)+1) * sizeof(char));
if (c_ptr == NULL)
return NULL;
return;
if (ptr->string)
- {
- if (ptr->root->call_free)
- ptr->root->call_free(ptr->root, ptr->string);
- else
- free(ptr->string);
- }
+ ptr->root->call_free(ptr->root, ptr->string);
if (ptr->is_allocated)
- {
- if (ptr->root->call_free)
- ptr->root->call_free(ptr->root, ptr);
- else
- free(ptr);
- }
+ ptr->root->call_free(ptr->root, ptr);
else
memset(ptr, 0, sizeof(memcached_string_st));
}
typedef void (*memcached_free_function)(memcached_st *ptr, void *mem);
typedef void *(*memcached_malloc_function)(memcached_st *ptr, const size_t size);
typedef void *(*memcached_realloc_function)(memcached_st *ptr, void *mem, const size_t size);
+typedef void *(*memcached_calloc_function)(memcached_st *ptr, size_t nelem, const size_t elsize);
typedef memcached_return (*memcached_execute_function)(memcached_st *ptr, memcached_result_st *result, void *context);
typedef memcached_return (*memcached_server_function)(memcached_st *ptr, memcached_server_st *server, void *context);
typedef memcached_return (*memcached_trigger_key)(memcached_st *ptr,
static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
{
- return calloc(1, size);
+ void *ret= malloc(size);
+ if (ret != NULL)
+ memset(ret, 0xff, size);
+
+ return ret;
}
static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
return realloc(mem, size);
}
+static void *my_calloc(memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size)
+{
+ return calloc(nelem, size);
+}
+
static memcached_return set_prefix(memcached_st *memc)
{
memcached_return rc;
return MEMCACHED_SUCCESS;
}
-static memcached_return set_memory_alloc(memcached_st *memc)
+static memcached_return deprecated_set_memory_alloc(memcached_st *memc)
{
void *test_ptr= NULL;
void *cb_ptr= NULL;
assert(rc == MEMCACHED_SUCCESS);
assert(test_ptr == cb_ptr);
}
+ return MEMCACHED_SUCCESS;
+}
+
+static memcached_return set_memory_alloc(memcached_st *memc)
+{
+ memcached_return rc;
+ rc= memcached_set_memory_allocators(memc, NULL, my_free,
+ my_realloc, my_calloc);
+ assert(rc == MEMCACHED_FAILURE);
+
+ rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
+ my_realloc, my_calloc);
+
+ memcached_malloc_function mem_malloc;
+ memcached_free_function mem_free;
+ memcached_realloc_function mem_realloc;
+ memcached_calloc_function mem_calloc;
+ memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
+ &mem_realloc, &mem_calloc);
+
+ assert(mem_malloc == my_malloc);
+ assert(mem_realloc == my_realloc);
+ assert(mem_calloc == my_calloc);
+ assert(mem_free == my_free);
return MEMCACHED_SUCCESS;
}
{"poll_timeout", poll_timeout, 0, tests},
{"gets", enable_cas, 0, tests},
{"consistent", enable_consistent, 0, tests},
+ {"deprecated_memory_allocators", deprecated_set_memory_alloc, 0, tests},
{"memory_allocators", set_memory_alloc, 0, tests},
{"prefix", set_prefix, 0, tests},
{"version_1_2_3", check_for_1_2_3, 0, version_1_2_3},