2
0
Эх сурвалжийг харах

wrapper memory functions transformed to macros (better debugging), modified
message allocation philosophy in message queues and updated documentation

Vaclav Kubart 20 жил өмнө
parent
commit
abab9ea7cb

+ 46 - 0
lib/cds/doc/cds_free_ptr.xml

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
+   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="cds_free_ptr"> <!-- ID for references -->
+
+<refmeta>
+<refentrytitle>cds_free_ptr</refentrytitle> <!-- title shown in references -->
+<manvolnum>3</manvolnum></refmeta> <!-- man volume id (3 for libraries) -->
+
+<refnamediv>
+<refname>cds_free_ptr</refname> <!-- function name -->
+<refpurpose>pointer to cds_free function independent on cds_free
+implementation (macro, ...)</refpurpose> <!-- short function description -->
+</refnamediv>
+
+<refsynopsisdiv><funcsynopsis>
+<funcsynopsisinfo>
+#include &lt;cds/memory.h&gt; <!-- included headers -->
+</funcsynopsisinfo>
+
+<funcprototype> <!-- function prototype -->
+  <funcdef>void <function>cds_free_ptr</function></funcdef>
+  <paramdef>void *<parameter>ptr</parameter></paramdef>
+</funcprototype>
+
+</funcsynopsis></refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para>Pointer to memory deallocation function. It is independent on
+<function>cds_free</function> implementation.
+<!-- detailed description -->
+</para>
+
+</refsect1>
+
+<refsect1><title>See Also</title>
+<para>
+<xref linkend="cds_free"/>
+<!-- references to other pages -->
+</para>
+</refsect1>
+
+</refentry> 
+

+ 2 - 2
lib/cds/doc/cds_malloc.xml

@@ -20,8 +20,8 @@
 </funcsynopsisinfo>
 
 <funcprototype> <!-- function prototype -->
-  <funcdef>int <function>cds_malloc</function></funcdef>
-  <paramdef>int <parameter>size</parameter></paramdef>
+  <funcdef>void *<function>cds_malloc</function></funcdef>
+  <paramdef>unsigned int <parameter>size</parameter></paramdef>
 </funcprototype>
 
 </funcsynopsis></refsynopsisdiv>

+ 46 - 0
lib/cds/doc/cds_malloc_ptr.xml

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
+   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="cds_malloc_ptr"> <!-- ID for references -->
+
+<refmeta>
+<refentrytitle>cds_malloc_ptr</refentrytitle> <!-- title shown in references -->
+<manvolnum>3</manvolnum></refmeta> <!-- man volume id (3 for libraries) -->
+
+<refnamediv>
+<refname>cds_malloc_ptr</refname> <!-- function name -->
+<refpurpose>pointer to cds_malloc function independent on cds_malloc
+implementation (macro, ...)</refpurpose> <!-- short function description -->
+</refnamediv>
+
+<refsynopsisdiv><funcsynopsis>
+<funcsynopsisinfo>
+#include &lt;cds/memory.h&gt; <!-- included headers -->
+</funcsynopsisinfo>
+
+<funcprototype> <!-- function prototype -->
+  <funcdef>void *<function>cds_malloc_ptr</function></funcdef>
+  <paramdef>unsigned int <parameter>size</parameter></paramdef>
+</funcprototype>
+
+</funcsynopsis></refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para>Pointer to memory allocation function. It is independent on
+<function>cds_malloc</function> implementation.
+<!-- detailed description -->
+</para>
+
+</refsect1>
+
+<refsect1><title>See Also</title>
+<para>
+<xref linkend="cds_malloc"/>
+<!-- references to other pages -->
+</para>
+</refsect1>
+
+</refentry> 
+

+ 3 - 9
lib/cds/doc/free_message.xml

@@ -32,23 +32,17 @@
 if they are allocated implicitly, it is freed together with message. Thus simple
 data strutures are deallocated automaticaly in both cases. There might be a
 problem with more complicated structures with internal pointers to other
-structures - these are NOT deallocated automaticaly because this function can't
-know the internal data structure and they must be freed by the
-caller!
+structures - for these you can set destroy function using
+<function>set_data_destroy_function</function>.
 <!-- detailed description -->
 </para>
 
-<para>This function does NOT free messages which were initialized using
-<function>message_init_ex</function> with <parameter>auto_free</parameter> not
-set, they must be freed explicitly by caller!
-</para>
-
 </refsect1>
 
 <refsect1><title>See Also</title>
 <para>
 <xref linkend="create_message"/>, <xref linkend="create_message_ex"/>, <xref
-linkend="init_message_ex"/>
+linkend="init_message_ex"/>, <xref linkend="set_data_destroy_function"/>
 <!-- references to other pages -->
 </para>
 </refsect1>

+ 9 - 7
lib/cds/doc/init_message_ex.xml

@@ -24,18 +24,20 @@
   <paramdef>mq_message_t *<parameter>m</parameter></paramdef>
   <paramdef>void *<parameter>data</parameter></paramdef>
   <paramdef>int <parameter>data_len</parameter></paramdef>
-  <paramdef>int <parameter>auto_free</parameter></paramdef>
+  <paramdef>destroy_function_f <parameter>func</parameter></paramdef>
 </funcprototype>
 
 </funcsynopsis></refsynopsisdiv>
 
 <refsect1><title>Description</title>
-<para>Initializes message structure with given data and given data length. If
-<parameter>auto_free</parameter> is set, the message can be be freed
-using <function>free_message</function> and such unremoved messages are freed
-automaticaly with <function>msg_queue_destroy</function>. If this flag is not set,
-calling <function>free message</function> will not do anything and the message
-and message data must be freed explicitly by caller.
+<para>Initializes message structure with given data and given data length like
+<function>create_message</function> but without its allocation. </para>
+<para>
+Parameter <parameter>func</parameter> specifies function called on data pointer
+before freeing the message in <function>free_message</function>. It can be NULL.
+This function may be used for example for memory deallocation (for example may
+have value of <function>cds_free_ptr</function>) or some more complicated
+function for freeing complex data structure with pointers inside or so.
 <!-- detailed description -->
 </para>
 

+ 12 - 2
lib/cds/doc/memory.xml

@@ -9,11 +9,19 @@
 <partintro>
 <para>Memory operations are common for whole CDS library. Because it must work
 together with SER's memory management and must work without it too, there are
+wrapper macros for memory allocation/deallocation.</para>
+
+<para>These macros were functions and it may change in the future, but macros
+are probably better - they allow better debuging than functions. There are
+defined another macros (see <xref linkend="cds_malloc_ptr"/>, <xref
+linkend="cds_free_ptr"/>), which point and will point to allocation/deallocation
+functions, thus they may be used as function pointers.
+<!--
 standalone functions (?macros in the future?) which cover internal
-implementation of memory allocation/deallocation functions.
+implementation of memory allocation/deallocation functions.-->
 </para>
 
-<para>It is possible to redefine these functions to help with memory debugging
+<para>It is possible to redefine these macros/functions to help with memory debugging
 or for monitoring purposes or so.
 </para>
 
@@ -26,4 +34,6 @@ with a memory debugging tool like valgrind
 <include xmlns="http://www.w3.org/2001/XInclude" href="cds_malloc.xml"/>
 <include xmlns="http://www.w3.org/2001/XInclude" href="cds_free.xml"/>
 
+<include xmlns="http://www.w3.org/2001/XInclude" href="cds_malloc_ptr.xml"/>
+<include xmlns="http://www.w3.org/2001/XInclude" href="cds_free_ptr.xml"/>
 </reference>

+ 2 - 6
lib/cds/doc/mq_message_t.xml

@@ -19,6 +19,7 @@ typedef struct _mq_message_t {
 	void *data;
 	int data_len;
 	struct _mq_message_t *next;
+	destroy_function_f destroy_function;
 	enum { 
 		message_allocated_with_data, 
 		message_holding_data_ptr 
@@ -45,14 +46,9 @@ message data should be obtained by <function>get_message_data</function>.
 	it after structure allocation, see <xref linkend="create_message_ex"/></para></listitem>
 
 	<listitem><para>there is third possibility, that data and message - both -
-	are allocated/freed by caller without using
+	are allocated by caller without using
 	<function>create_message</function>, <function>create_message_ex</function> and 
 	<function>msg_free</function>, see <xref linkend="init_message_ex"/></para>
-<!--	<para>In this case might be the <structname>mq_message_t</structname> for
-	example a part of the data structure.</para>
-	<para>This is not recomended because of
-	future possibility of <quote>network message queues</quote> and the
-	framework between could not free message memory.</para>-->
 	</listitem>
 </itemizedlist>
 </para>

+ 1 - 0
lib/cds/doc/msg_queue.xml

@@ -30,6 +30,7 @@
 <include xmlns="http://www.w3.org/2001/XInclude" href="create_message.xml"/>
 <include xmlns="http://www.w3.org/2001/XInclude" href="create_message_ex.xml"/>
 <include xmlns="http://www.w3.org/2001/XInclude" href="init_message_ex.xml"/>
+<include xmlns="http://www.w3.org/2001/XInclude" href="set_data_destroy_function.xml"/>
 <include xmlns="http://www.w3.org/2001/XInclude" href="free_message.xml"/>
 
 </reference>

+ 1 - 2
lib/cds/doc/msg_queue_destroy.xml

@@ -33,9 +33,8 @@ manipulation functions except <function>msg_queue_init</function>.
 <!-- detailed description -->
 </para>
 
-<para>All messages which stay in the queue and have <parameter>auto_free</parameter> flag set 
+<para>All messages which stay in the queue  
 are automaticaly freed using <function>free_message</function>. 
-It depends on allocation manner of messages if it is sufficient.
 </para>
 
 </refsect1>

+ 71 - 0
lib/cds/doc/set_data_destroy_function.xml

@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
+   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="set_data_destroy_function"> <!-- ID for references -->
+
+<refmeta>
+<refentrytitle>set_data_destroy_function</refentrytitle> <!-- title shown in references -->
+<manvolnum>3</manvolnum></refmeta> <!-- man volume id (3 for libraries) -->
+
+<refnamediv>
+<refname>set_data_destroy_function</refname> <!-- function name -->
+<refpurpose>set function used to deallocate message data</refpurpose> <!-- short function description -->
+</refnamediv>
+
+<refsynopsisdiv><funcsynopsis>
+<funcsynopsisinfo>
+#include &lt;cds/msg_queue.h&gt; <!-- included headers -->
+
+typedef void (*destroy_function_f)(void *);
+</funcsynopsisinfo>
+
+<funcprototype> <!-- function prototype -->
+  <funcdef>void <function>set_data_destroy_function</function></funcdef>
+  <paramdef>mq_message_t *<parameter>msg</parameter></paramdef>
+  <paramdef>destroy_function_f <parameter>func</parameter></paramdef>
+</funcprototype>
+
+</funcsynopsis></refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para>Set destroy function for message data. This function is called from
+<function>free_message</function> and is primarily used for deallocation of
+complex data structures or their content. It can be used on all types of
+messages (allocated using <function>create_message</function> or
+<function>create_message_ex</function> or initialized using
+<function>init_message_ex</function>).
+<!-- detailed description -->
+</para>
+
+<example><title>Usage with create_message_ex</title>
+<programlisting>
+str_t *s;
+mq_message_t *msg = create_message_ex(sizeof(str_t));
+set_data_destroy_function((destroy_function_f)str_free_content);
+s = (str_t*)get_message_data(msg);
+str_dup_zt(s, "something happened");
+</programlisting>
+</example>
+
+<example><title>Usage with create_message</title>
+<programlisting>
+str_t *s = cds_malloc(sizeof(str_t));
+mq_message_t *msg = create_message(s, sizeof(str_t));
+set_data_destroy_function((destroy_function_f)str_free);
+str_dup_zt(s, "something happened");
+</programlisting>
+</example>
+
+</refsect1>
+
+<refsect1><title>See Also</title>
+<para><xref linkend="create_message"/>, <xref linkend="create_message_ex"/>,
+<xref linkend="init_message_ex"/>
+<!-- references to other pages -->
+</para>
+</refsect1>
+
+</refentry> 
+

+ 6 - 5
lib/cds/hash_table.c

@@ -24,6 +24,7 @@
  */
 
 #include <cds/hash_table.h>
+#include <cds/memory.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -33,7 +34,7 @@ int ht_init(hash_table_t *ht, hash_func_t hash_func, key_cmp_func_t cmp_keys, in
 	if (!ht) return -1;
 	if ((!hash_func) || (!cmp_keys)) return -1;
 
-	ht->cslots = (ht_cslot_t*)malloc(size * sizeof(ht_cslot_t));
+	ht->cslots = (ht_cslot_t*)cds_malloc(size * sizeof(ht_cslot_t));
 	if (!ht->cslots) return -1;
 	memset(ht->cslots, 0, size * sizeof(ht_cslot_t));
 
@@ -59,11 +60,11 @@ void ht_destroy(hash_table_t *ht)
 			e = ht->cslots[i].first;
 			while (e) {
 				n = e->next;
-				free(e);
+				cds_free(e);
 				e = n;
 			}
 		}
-		free(ht->cslots);
+		cds_free(ht->cslots);
 	}
 	ht->cslots = NULL;
 }
@@ -74,7 +75,7 @@ int ht_add(hash_table_t *ht, ht_key_t key, ht_data_t data)
 	ht_element_t *new_e;
 	
 	if (!ht) return -1;
-	new_e = (ht_element_t*)malloc(sizeof(ht_element_t));
+	new_e = (ht_element_t*)cds_malloc(sizeof(ht_element_t));
 	if (!new_e) return -1;
 	new_e->next = NULL;
 	new_e->key = key;
@@ -136,7 +137,7 @@ ht_data_t ht_remove(hash_table_t *ht, ht_key_t key)
 			ht->cslots[h].cnt--;
 			if (!e->next) ht->cslots[h].last = p;
 			data = e->data;
-			free(e);
+			cds_free(e);
 			return data;
 		}
 		p = e;

+ 63 - 103
lib/cds/memory.c

@@ -29,137 +29,97 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <cds/memory.h>
+#include <cds/sync.h>
+#include <cds/logger.h>
 
-#ifdef SER
-
-#include <mem/mem.h>
-#include <mem/shm_mem.h>
-
-static void* shm_malloc_x(unsigned int size);
-static void shm_free_x(void *ptr);
+#ifdef TRACE_CDS_MEMORY
 
-cds_malloc_func cds_malloc = shm_malloc_x;
-cds_free_func cds_free = shm_free_x;
+cds_mutex_t *mem_mutex = NULL;
+int *allocated_cnt = NULL;
+char *debug_file = "/tmp/mem.log";
+
+#define write_debug(s,args...)	if (1) { \
+	FILE *f = fopen(debug_file, "a"); \
+	if (f) { \
+		fprintf(f,s,##args); \
+		fclose(f); \
+	} \
+	TRACE_LOG(s,##args); \
+}
 
+void *debug_malloc(int size, const char *file, int line)
+{
+	void *m = NULL;
+	if (allocated_cnt && mem_mutex) {
+		cds_mutex_lock(mem_mutex);
+		(*allocated_cnt)++;
+		cds_mutex_unlock(mem_mutex);
+	}
+#ifdef SER
+	m = shm_malloc(size);
 #else
-
-cds_malloc_func cds_malloc = malloc;
-cds_free_func cds_free = free;
-
+	m = malloc(size);
 #endif
-
-void cds_set_memory_functions(cds_malloc_func _malloc, cds_free_func _free)
-{
-	cds_malloc = _malloc;
-	cds_free = _free;
+	write_debug("ALLOC %p size %u from %s(%d)\n", m, size, file, line);
+	/* LOG(L_INFO, "debug_malloc(): %p\n", m); */
+	return m;
 }
 
+void debug_free(void *block, const char *file, int line)
+{
+	if (allocated_cnt && mem_mutex) {
+		cds_mutex_lock(mem_mutex);
+		(*allocated_cnt)--;
+		cds_mutex_unlock(mem_mutex);
+	}
 #ifdef SER
+	shm_free(block);
+#else
+	free(block);
+#endif
+	write_debug("FREE %p from %s(%d)\n", block, file, line);
+}
 
-static void* shm_malloc_x(unsigned int size)
+void *debug_malloc_ex(unsigned int size)
 {
-	return shm_malloc(size);
+	return debug_malloc(size, "<none>", 0);
 }
 
-static void shm_free_x(void *ptr)
+void debug_free_ex(void *block)
 {
-	shm_free(ptr);
+	debug_free(block, "<none>", 0);
 }
 
-#endif
-
-/*
-#ifdef SER
-
-static gen_lock_t *mem_mutex = NULL;
-int *allocated_cnt = NULL;
-
-#else
-
-static int allocated_cnt = 0;
-
-#endif
-
-void debug_mem_init()
+void cds_memory_trace_init()
 {
-#ifdef SER
-	mem_mutex = lock_alloc();
-	allocated_cnt = shm_malloc(sizeof(int));
+	cds_mutex_init(mem_mutex);
+	allocated_cnt = cds_malloc(sizeof(int));
 	*allocated_cnt = 0;
-	debug_print_allocated_mem();
-#else
-	allocated_cnt = 0;
-#endif
 }
 
-void *debug_malloc(int size)
+void cds_memory_trace(char *dst, int dst_len)
 {
-#ifdef SER
-	void *m = NULL;
-	lock_get(mem_mutex);
-	if (allocated_cnt) (*allocated_cnt)++;
-	lock_release(mem_mutex);
-	m = shm_malloc(size);
-	LOG(L_INFO, "debug_malloc(): %p\n", m);
-	return m;
-#else
-	allocated_cnt++;
-	return malloc(size);
-#endif
+	if (allocated_cnt && mem_mutex) {
+		cds_mutex_lock(mem_mutex);
+		snprintf(dst, dst_len, "There are allocated: %d memory blocks\n", *allocated_cnt);
+		cds_mutex_unlock(mem_mutex);
+	}
 }
 
-void debug_free(void *block)
-{
+#else /* ! CDS_TRACE_MEMORY */
+
 #ifdef SER
-	LOG(L_INFO, "debug_free(): %p\n", block);
-	shm_free(block);
-	lock_get(mem_mutex);
-	if (allocated_cnt) (*allocated_cnt)--;
-	lock_release(mem_mutex);
-#else
-	free(block);
-	allocated_cnt--;
-#endif
-}
 
-void *debug_malloc_ex(int size, const char *file, int line)
+void* shm_malloc_x(unsigned int size)
 {
-#ifdef SER
-	void *m = NULL;
-	lock_get(mem_mutex);
-	if (allocated_cnt) (*allocated_cnt)++;
-	lock_release(mem_mutex);
-	m = shm_malloc(size);
-	LOG(L_INFO, "ALLOC: %s:%d -> %p\n", file, line, m);
-	return m;
-#else
-	allocated_cnt++;
-	return malloc(size);
-#endif
+	return shm_malloc(size);
 }
 
-void debug_free_ex(void *block, const char *file, int line)
+void shm_free_x(void *ptr)
 {
-#ifdef SER
-	LOG(L_INFO, "FREE: %s:%d -> %p\n", file, line, block);
-	shm_free(block);
-	lock_get(mem_mutex);
-	if (allocated_cnt) (*allocated_cnt)--;
-	lock_release(mem_mutex);
-#else
-	free(block);
-	allocated_cnt--;
-#endif
+	shm_free(ptr);
 }
 
-void debug_print_allocated_mem()
-{
-#ifdef SER
-	lock_get(mem_mutex);
-	LOG(L_INFO, "There are allocated: %d memory blocks\n", *allocated_cnt);
-	lock_release(mem_mutex);
-#else
-	printf("There are allocated: %d memory blocks\n", allocated_cnt);
 #endif
-}
-*/
+
+#endif

+ 49 - 2
lib/cds/memory.h

@@ -26,17 +26,64 @@
 #ifndef __CDS_MEMORY_H
 #define __CDS_MEMORY_H
 
+/* #define TRACE_CDS_MEMORY */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef void*(*cds_malloc_func)(unsigned int size);
+/* typedef void*(*cds_malloc_func)(unsigned int size);
 typedef void(*cds_free_func)(void *ptr);
 
 extern cds_malloc_func cds_malloc;
 extern cds_free_func cds_free;
 
-void cds_set_memory_functions(cds_malloc_func _malloc, cds_free_func _free);
+void cds_set_memory_functions(cds_malloc_func _malloc, cds_free_func _free); */
+
+#ifdef TRACE_CDS_MEMORY
+
+void *debug_malloc(int size, const char *file, int line);
+void debug_free(void *block, const char *file, int line);
+void *debug_malloc_ex(unsigned int size);
+void debug_free_ex(void *block);
+
+/* trace function */
+void cds_memory_trace(char *dst, int dst_len);
+/* initializes internal variables for memory tracing */
+void cds_memory_trace_init();
+
+#define cds_malloc(s)	debug_malloc(s,__FILE__, __LINE__)
+#define cds_free(p)		debug_free(p,__FILE__, __LINE__)
+#define cds_free_ptr	debug_free_ex
+#define cds_malloc_ptr	debug_malloc_ex
+
+#else /* !TRACE */
+
+#ifdef SER
+
+#include <mem/mem.h>
+#include <mem/shm_mem.h>
+
+void* shm_malloc_x(unsigned int size);
+void shm_free_x(void *ptr);
+
+#define cds_malloc(s)	shm_malloc(s)
+#define cds_free(p)		shm_free(p)
+#define cds_malloc_ptr	shm_malloc_x
+#define cds_free_ptr	shm_free_x
+
+#else /* !SER */
+
+#include <stdlib.h>
+
+#define cds_malloc(s)	malloc(s)
+#define cds_free(p)		free(p)
+#define cds_malloc_ptr	malloc
+#define cds_free_ptr	free
+
+#endif /* !SER */
+
+#endif /* !TRACE_CDS_MEMORY */
 
 #ifdef __cplusplus
 }

+ 13 - 7
lib/cds/msg_queue.c

@@ -37,6 +37,7 @@ mq_message_t *create_message_ex(int data_len)
 	m->data = (((char *)m) + sizeof(mq_message_t));
 	m->next = NULL;
 	m->allocation_style = message_allocated_with_data;
+	m->destroy_function = NULL;
 	return m;
 }
 
@@ -50,10 +51,11 @@ mq_message_t *create_message(void *data, int data_len)
 	m->data = data;
 	m->next = NULL;
 	m->allocation_style = message_holding_data_ptr;
+	m->destroy_function = cds_free_ptr;
 	return m;
 }
 
-void init_message_ex(mq_message_t *m, void *data, int data_len, int auto_free)
+void init_message_ex(mq_message_t *m, void *data, int data_len, destroy_function_f func)
 {
 	/* if (data_len < 0) data_len = 0; */
 	if (!m) return;
@@ -61,21 +63,25 @@ void init_message_ex(mq_message_t *m, void *data, int data_len, int auto_free)
 	m->data_len = data_len;
 	m->data = data;
 	m->next = NULL;
-	if (auto_free) m->allocation_style = message_holding_data_ptr;
-	else m->allocation_style = message_holding_data_ptr_no_free;
+	m->destroy_function = func;
+	m->allocation_style = message_holding_data_ptr;
+}
+
+void set_data_destroy_function(mq_message_t *msg, destroy_function_f func)
+{
+	if (msg) msg->destroy_function = func;
 }
 
 void free_message(mq_message_t *msg)
 {
+	if (msg->destroy_function && msg->data) 
+		msg->destroy_function(msg->data);
 	switch (msg->allocation_style) {
 		case message_allocated_with_data: 
 				break;
 		case message_holding_data_ptr: 
-				if (msg->data) cds_free(msg->data);
+				/* if (msg->data) cds_free(msg->data); */
 				break;
-		case message_holding_data_ptr_no_free:
-				/* not automaticaly freed !! */
-				return;
 	}
 	cds_free(msg);
 }

+ 7 - 3
lib/cds/msg_queue.h

@@ -28,14 +28,16 @@
 
 #include <cds/sync.h>
 
+typedef void (*destroy_function_f)(void *);
+
 typedef struct _mq_message_t {
 	void *data;
 	int data_len;
 	struct _mq_message_t *next;
+	destroy_function_f destroy_function; /* see doc */
 	enum { 
 		message_allocated_with_data, 
-		message_holding_data_ptr, 
-		message_holding_data_ptr_no_free /* not automaticaly freed */
+		message_holding_data_ptr
 	} allocation_style;
 	char data_buf[1];
 } mq_message_t;
@@ -59,10 +61,12 @@ mq_message_t *create_message_ex(int data_len);
  * are automacicaly freed! */
 mq_message_t *create_message(void *data, int data_len);
 
+void set_data_destroy_function(mq_message_t *msg, destroy_function_f func);
+
 /** initializes message, 
  * if auto_free set, data must be allocated using cds_malloc and are automaticaly freed by free_message 
  * (and if msg_queue_destroy called) */
-void init_message_ex(mq_message_t *m, void *data, int data_len, int auto_free);
+void init_message_ex(mq_message_t *m, void *data, int data_len, destroy_function_f func);
 
 /** frees the message and data holding by the message !!!! */
 void free_message(mq_message_t *msg);

+ 3 - 3
lib/cds/sstr.c

@@ -163,13 +163,13 @@ int str_case_equals(const str_t *a, const str_t *b)
 	return 0;
 }
 
-void str_free_content(str_t *s)
+/* void str_free_content(str_t *s)
 {
 	if (!s) return;
 	if ((s->len > 0) && (s->s)) cds_free(s->s);
 	s->len = 0;
 	s->s = NULL;
-}
+} 
 
 void str_free(str_t *s)
 {
@@ -177,7 +177,7 @@ void str_free(str_t *s)
 		str_free_content(s);
 		cds_free(s);
 	}
-}
+}*/
 
 void str_clear(str_t *s)
 {

+ 13 - 2
lib/cds/sstr.h

@@ -26,6 +26,8 @@
 #ifndef __SIMPLE_STR_H
 #define __SIMPLE_STR_H
 
+#include <cds/memory.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -66,10 +68,19 @@ int str_dup_zt(str_t* dst, const char* src);
 char *zt_strdup(const char*src);
 
 /** frees string content if allocated */
-void str_free_content(str_t *s);
+/* void str_free_content(str_t *s); */
+#define str_free_content(str)	if (str) { \
+		if (((str)->len > 0) && ((str)->s)) cds_free((str)->s);\
+		(str)->len = 0; \
+		(str)->s = 0; \
+	}
 
 /** frees string content if allocated and then the string itself */
-void str_free(str_t *s);
+/* void str_free(str_t *s); */
+#define str_free(str)	if (str) { \
+		str_free_content(str); \
+		cds_free(str); \
+	}
 
 /** case sensitive comparation - returns 0 if equal, nonzero otherwise */
 int str_case_equals(const str_t *a, const str_t *b);

+ 0 - 15
lib/presence/doc/presence.xml

@@ -18,21 +18,6 @@
 representation and helper functions.
 </para>
 
-<section><title>Conventions</title>
-<para>There is list of conventions used in this library:
-<itemizedlist>
-	<listitem><para>data types (structures, enums, ...) have their names with suffix 
-	<quote>_t</quote> (<structname>dstring_t</structname>, 
-	<structname>str_t</structname>, ...)</para></listitem>
-	<listitem><para>many functions have prefix according to data structure on
-	which are operating (like <function>dstr_append</function> which operates on
-	<structname>dstring_t</structname> data structure)</para></listitem>
-	<listitem><para>most functions return 0 as successful result and nonzero
-	value as error</para></listitem>
-</itemizedlist>
-</para>
-</section>
-
 <section id="libpresence.dependencies"><title>Dependencies</title>
 <para>
 <itemizedlist>

+ 2 - 0
lib/presence/notifier_domain.c

@@ -249,6 +249,8 @@ void unregister_notifier(notifier_domain_t *domain, notifier_t *info)
 {
 	notifier_package_t *p;
 
+	if ((!info) || (!domain)) return;
+
 	/* maybe: test if the NOTIFIER is registered before unregistration */
 
 	lock_notifier_domain(domain);

+ 0 - 15
lib/xcap/doc/xcap.xml

@@ -17,21 +17,6 @@
 <para>This library contains functions for manipulating data using XCAP protocol.
 </para>
 
-<section><title>Conventions</title>
-<para>There is list of conventions used in this library:
-<itemizedlist>
-	<listitem><para>data types (structures, enums, ...) have their names with suffix 
-	<quote>_t</quote> (<structname>dstring_t</structname>, 
-	<structname>str_t</structname>, ...)</para></listitem>
-	<listitem><para>many functions have prefix according to data structure on
-	which are operating (like <function>dstr_append</function> which operates on
-	<structname>dstring_t</structname> data structure)</para></listitem>
-	<listitem><para>most functions return 0 as successful result and nonzero
-	value as error</para></listitem>
-</itemizedlist>
-</para>
-</section>
-
 <section id="libxcap.dependencies"><title>Dependencies</title>
 <para>
 <itemizedlist>

+ 1 - 1
lib/xcap/rls_services_parser.c

@@ -260,7 +260,7 @@ void free_service(service_t *s)
 
 	switch (s->content_type) {
 		case stc_list: free_list(s->content.list); break;
-		case stc_resource_list: free(s->content.resource_list); break;
+		case stc_resource_list: cds_free(s->content.resource_list); break;
 	}
 	
 	free_packages(s->packages);