Browse Source

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

Vaclav Kubart 20 năm trước cách đây
mục cha
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);