Module: sip-router
Branch: master
Commit: 141808e9c0789e56f29297e2d2c185e091ebb66a
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=141808e…
Author: Henning Westerholt <hw(a)kamailio.org>
Committer: Henning Westerholt <hw(a)kamailio.org>
Date: Thu May 2 23:41:28 2013 +0200
memcached: port to more recent memory manager callback structure
* port to more recent memory manager callback structure
* add small wrapper for calloc, implemented not optimal at the moment
because the pkg_calloc from core/mem is not exported yet
* add initial code to check for server connection during startup, not
enabled yet as its work in progress
* reorder structure a bit to allow for clean shutdown because of internal mm
---
modules/memcached/memcached.c | 110 ++++++++++++++++++++++++-----------------
1 files changed, 65 insertions(+), 45 deletions(-)
diff --git a/modules/memcached/memcached.c b/modules/memcached/memcached.c
index c72ccf1..32852d9 100644
--- a/modules/memcached/memcached.c
+++ b/modules/memcached/memcached.c
@@ -107,7 +107,7 @@ struct module_exports exports = {
* \param mem freed memory
* \see pkg_free
*/
-static inline void mcd_free(void *mem) {
+static inline void mcd_free(memcached_st *ptr, void *mem, void *context) {
pkg_free(mem);
}
@@ -118,7 +118,7 @@ static inline void mcd_free(void *mem) {
* \return allocated memory, or NULL on failure
* \see pkg_malloc
*/
-static inline void* mcd_malloc(const size_t size) {
+static inline void* mcd_malloc(memcached_st *ptr, const size_t size, void *context) {
return pkg_malloc(size);
}
@@ -130,10 +130,43 @@ static inline void* mcd_malloc(const size_t size) {
* \return allocated memory, or NULL on failure
* \see pkg_realloc
*/
-static inline void* mcd_realloc(void *mem, const size_t size) {
+static inline void* mcd_realloc(memcached_st *ptr, void *mem, const size_t size, void
*context) {
return pkg_realloc(mem, size);
}
+
+/*!
+ * \brief Wrapper functions around our internal memory management
+ * \param mem pointer to allocated memory
+ * \param size new size of memory area
+ * \return allocated memory, or NULL on failure
+ * \see pkg_malloc
+ * \todo this is not optimal, use internal calloc implemention which is not exported
yet
+ */
+static inline void * mcd_calloc(memcached_st *ptr, size_t nelem, const size_t elsize,
void *context) {
+ void* tmp = NULL;
+ tmp = pkg_malloc(nelem * elsize);
+ if (tmp != NULL) {
+ memset(tmp, 0, nelem * elsize);
+ }
+ return tmp;
+}
+
+/**
+ * \brief Callback to check if we could connect successfully to a server
+ * \param ptr memcached handler
+ * \param server server instance
+ * \param context context for callback
+ * \return MEMCACHED_SUCCESS on success, MEMCACHED_CONNECTION_FAILURE on failure
+ * \todo FIXME
+static inline memcached_server_fn mcd_check_connection(const memcached_st *ptr,
memcached_server_instance_st my_server, void *context) {
+ if (my_server->fd < 0) {
+ return MEMCACHED_CONNECTION_FAILURE;
+ }
+ return MEMCACHED_SUCCESS;
+}
+*/
+
/*!
* \brief Module initialization function
* \return 0 on success, -1 on failure
@@ -161,54 +194,25 @@ static int mod_init(void) {
strncpy(server, mcd_srv_str, len);
server[len] = '\0';
- servers = memcached_server_list_append(servers, server, atoi(port), &rc);
-
memcached_h = memcached_create(NULL);
if (memcached_h == NULL) {
LM_ERR("could not create memcached structure\n");
return -1;
}
LM_DBG("allocated new server handle at %p", memcached_h);
-
- #ifdef MEMCACHED_ENABLE_DEPRECATED
- /**
- * \note Set callbacks to our internal memory manager
- * \bug this don't work for now
- * \todo Move to new memcached_set_memory_allocators function, this deprecated since
0.32
- *
- * 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. The prototype
- * for this is:
- * void *(*memcached_malloc_function)(memcached_st *ptr, const size_t size);
- *
- * 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);
- *
- * 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);
- */
- LM_DBG("set memory manager callbacks");
- if (memcached_callback_set(memcached_h, MEMCACHED_CALLBACK_MALLOC_FUNCTION, mcd_free) !=
MEMCACHED_SUCCESS) {
- LM_ERR("could not set malloc callback handler");
- return -1;
- }
- if (memcached_callback_set(memcached_h, MEMCACHED_CALLBACK_REALLOC_FUNCTION,
mcd_realloc) != MEMCACHED_SUCCESS) {
- LM_ERR("could not set realloc callback handler");
- return -1;
- }
- if (memcached_callback_set(memcached_h, MEMCACHED_CALLBACK_FREE_FUNCTION, mcd_free) !=
MEMCACHED_SUCCESS) {
- LM_ERR("could not set free callback handler");
+
+ LM_DBG("set memory manager callbacks");
+ rc = memcached_set_memory_allocators(memcached_h, (memcached_malloc_fn)mcd_malloc,
+ (memcached_free_fn)mcd_free, (memcached_realloc_fn)mcd_realloc,
+ (memcached_calloc_fn)mcd_calloc, NULL);
+ if (rc == MEMCACHED_SUCCESS) {
+ LM_DBG("memory manager callbacks set");
+ } else {
+ LM_ERR("memory manager callbacks not set, returned %s.\n",
memcached_strerror(memcached_h, rc));
return -1;
}
- LM_DBG("memory manager callbacks set");
- #endif
+
+ servers = memcached_server_list_append(servers, server, atoi(port), &rc);
if (memcached_behavior_set(memcached_h, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, mcd_timeout)
!= MEMCACHED_SUCCESS) {
LM_ERR("could not set server connection timeout");
@@ -223,6 +227,10 @@ static int mod_init(void) {
}
pkg_free(server);
+
+ /** \todo FIXME logic to handle connection errors on startup
+ memcached_server_cursor(memcached_h, (const memcached_server_fn*)
&mcd_check_connection, NULL, 1);
+ */
LM_INFO("libmemcached version is %s\n", memcached_lib_version());
return 0;
@@ -233,8 +241,20 @@ static int mod_init(void) {
* \brief Module shutdown function
*/
static void mod_destroy(void) {
- if (memcached_h != NULL)
- memcached_free(memcached_h);
+ memcached_return rc;
+
if (servers != NULL)
memcached_server_list_free(servers);
+
+ /* unset custom memory manager to enable clean shutdown of in system memory allocated
server structure */
+ LM_DBG("remove memory manager callbacks");
+ rc = memcached_set_memory_allocators(memcached_h, NULL, NULL, NULL, NULL, NULL);
+ if (rc == MEMCACHED_SUCCESS) {
+ LM_DBG("memory manager callbacks removed");
+ } else {
+ LM_ERR("memory manager callbacks not removed, returned %s but continue
anyway.\n", memcached_strerror(memcached_h, rc));
+ }
+
+ if (memcached_h != NULL)
+ memcached_free(memcached_h);
}