freeswitch/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c

1720 lines
42 KiB
C
Raw Normal View History

/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2005 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include "config.h"
/**@defgroup su_alloc Memory Management Tutorial
*
* This page gives a short overview of home-based memory management used
* with Sofia. Such home-based memory management is useful when a lot of
* memory blocks are allocated for given task. The allocations are done via
* the @e memory @e home, which keeps a reference to each block. When the
* memory home is then freed, it will free all blocks to which it has
* reference.
*
* Typically, there is a @e home @e object which contains a su_home_t
* structure in the beginning of the object (sort of inheritance from
* su_home_t):
* @code
* struct context {
* su_home_t ctx_home[1];
* other_t *ctx_stuff;
* ...
* }
* @endcode
*
* A new home memory pool can be created with su_home_new():
* @code
* struct context *ctx = su_home_new(sizeof (struct context));
* @endcode
*
* It is also possible to create a secondary memory pool that can be
* released separately:
*
* @code
* struct context *ctx = su_home_clone(tophome, sizeof (struct context));
* @endcode
*
* Note that the tophome has a reference to @a ctx structure; whenever
* tophome is freed, the @a ctx is also freed.
*
* You can also create an independent home object by passing NULL as @a
* tophome argument. This is identical to the call to su_home_new().
*
* The memory allocations using @a ctx proceed then as follows:
* @code
* zeroblock = su_zalloc(ctx->ctx_home, sizeof (*zeroblock));
* @endcode
*
* The home memory pool - the home object and all the memory blocks
* allocated using it - are freed when su_home_unref() is called:
*
* @code
* su_home_unref(ctx->ctx_home).
* @endcode
*
* @note For historical reasons, su_home_unref() is also known as
* su_home_zap().
*
* As you might have guessed, it is also possible to use reference counting
* with home objects. The function su_home_ref() increases the reference
* count, su_home_unref() decreases it. A newly allocated or initialized
* home object has reference count of 1.
*
* @note Please note that while it is possible to create new references to
* secondary home objects which have a parent home, the secondary home
* objects will always be destroyed when the parent home is destroyed even
* if there are other references left to them.
*
* The memory blocks in a cloned home object are freed when the object with
* home itself is freed:
* @code
* su_free(tophome, ctx);
* @endcode
*
* @note
*
* The su_home_destroy() function is deprecated as it does not free the home
* object itself. Like su_home_deinit(), it should be called only on home
* objects with reference count of 1.
*
* The function su_home_init() initializes a home object structure. When the
* initialized home object is destroyed or deinitialized or its reference
* count reaches zero, the memory allocate thorugh it reclaimed but the home
* object structure itself is not freed.
*
* @section su_home_destructor_usage Destructors
*
* It is possible to give a destructor function to a home object. The
* destructor releases other resources associated with the home object
* besides memory. The destructor function will be called when the reference
* count of home reaches zero (upon calling su_home_unref()) or the home
* object is otherwise deinitialized (calling su_home_deinit() on
* objects allocated from stack).
*
* @section su_home_move_example Combining Allocations
*
* In some cases, an operation that makes multiple memory allocations may
* fail, making those allocations redundant. If the allocations are made
* through a temporary home, they can be conveniently freed by calling
* su_home_deinit(), for instance. If, however, the operation is successful,
* and one wants to keep the allocations, the allocations can be combined
* into an existing home with su_home_move(). For example,
* @code
* int example(su_home_t *home, ...)
* {
* su_home_t temphome[1] = { SU_HOME_INIT(temphome) };
*
* ... do lot of allocations with temphome ...
*
* if (success)
* su_home_move(home, temphome);
* su_home_deinit(temphome);
*
* return success;
* }
* @endcode
*
* Note that the @a temphome is deinitialized in every case, but when
* operation is successful, the allocations are moved from @a temphome to @a
* home.
*
* @section su_alloc_threadsafe Threadsafe Operation
*
* If multiple threads need to access same home object, it must be marked as
* @e threadsafe by calling su_home_threadsafe() with the home pointer as
* argument. The threadsafeness is not inherited by clones.
*
* The threadsafe home objects can be locked and unlocked with
* su_home_mutex_lock() and su_home_mutex_unlock(). These operations are
* no-op on home object that is not threadsafe.
*
* @section su_alloc_preloading Preloading a Memory Home
*
* In some situations there is quite heavy overhead if the global heap
* allocator is used. The overhead caused by the large number of small
* allocations can be reduced by using su_home_preload(): it allocates or
* preloads some a memory to home to be used as a kind of private heap. The
* preloaded memory area is then used to satisfy small enough allocations.
* For instance, the SIP parser typically preloads some 2K of memory when it
* starts to parse the message.
*
* @section su_alloc_stack Using Stack
*
* In some situation, it is sensible to use memory allocated from stack for
* some operations. The su_home_auto() function can be used for that
* purpose. The memory area from stack is used to satisfy the allocations as
* far as possible; if it is not enough, allocation is made from heap.
*
* The word @e auto refers to the automatic scope; however, the home object
* that was initialized with su_home_auto() must be explicitly deinitialized
* with su_home_deinit() or su_home_unref() when the program exits the scope
* where the stack frame used in su_home_auto() was allocated.
*/
Sync to current darcs tree: Mon Sep 17 14:50:04 EDT 2007 Pekka.Pessi@nokia.com * sofia-sip/sip_util.h: updated documentation Mon Sep 17 14:50:18 EDT 2007 Pekka.Pessi@nokia.com * sofia-sip/tport_tag.h: updated documentation Mon Sep 17 14:50:28 EDT 2007 Pekka.Pessi@nokia.com * soa_tag.c: updated documentation Wed Sep 19 12:50:01 EDT 2007 Pekka.Pessi@nokia.com * msg: updated documentation Wed Sep 19 13:29:50 EDT 2007 Pekka.Pessi@nokia.com * url: updated documentation Wed Sep 19 13:32:14 EDT 2007 Pekka.Pessi@nokia.com * nth: updated documentation Wed Sep 19 13:32:27 EDT 2007 Pekka.Pessi@nokia.com * nea: updated documentation Wed Sep 19 13:33:36 EDT 2007 Pekka.Pessi@nokia.com * http: updated documentation Wed Sep 19 13:36:58 EDT 2007 Pekka.Pessi@nokia.com * bnf: updated documentation Wed Sep 19 13:38:58 EDT 2007 Pekka.Pessi@nokia.com * nua: updated nua_stack_init_handle() prototype Wed Sep 19 18:45:56 EDT 2007 Pekka.Pessi@nokia.com * sip: added sip_name_addr_xtra(), sip_name_addr_dup() Wed Sep 19 19:00:19 EDT 2007 Pekka.Pessi@nokia.com * sip_basic.c: cleaned old crud Thu Sep 20 13:34:04 EDT 2007 Pekka.Pessi@nokia.com * iptsec: updated documentation Thu Sep 20 13:36:22 EDT 2007 Pekka.Pessi@nokia.com * tport: updated documentation Thu Sep 20 13:36:56 EDT 2007 Pekka.Pessi@nokia.com * su: updated documentation Removed internal files from doxygen-generated documentation. Thu Sep 20 13:38:29 EDT 2007 Pekka.Pessi@nokia.com * soa: fixed documentation Thu Sep 20 13:39:56 EDT 2007 Pekka.Pessi@nokia.com * sdp: updated documentation Thu Sep 20 13:40:16 EDT 2007 Pekka.Pessi@nokia.com * ipt: updated documentation Thu Sep 20 14:24:20 EDT 2007 Pekka.Pessi@nokia.com * nta: updated documentation Thu Sep 20 14:41:04 EDT 2007 Pekka.Pessi@nokia.com * nua: updated documentation Updated tag documentation. Moved doxygen doc entries from sofia-sip/nua_tag.h to nua_tag.c. Removed internal datatypes and files from the generated documents. Wed Sep 19 13:34:20 EDT 2007 Pekka.Pessi@nokia.com * docs: updated the generation of documentation. Updated links to header files. Thu Sep 20 08:45:32 EDT 2007 Pekka.Pessi@nokia.com * sip/Makefile.am: added tags to <sofia-sip/sip_extra.h> Added check for extra tags in torture_sip.c. Thu Sep 20 14:45:22 EDT 2007 Pekka.Pessi@nokia.com * stun: updated documentation Wed Jul 4 18:55:20 EDT 2007 Pekka.Pessi@nokia.com * torture_heap.c: added tests for ##sort() and su_smoothsort() Wed Jul 4 18:56:59 EDT 2007 Pekka.Pessi@nokia.com * Makefile.am: added smoothsort.c Fri Jul 13 12:38:44 EDT 2007 Pekka.Pessi@nokia.com * sofia-sip/heap.h: heap_remove() now set()s index to 0 on removed item Mon Jul 23 11:14:22 EDT 2007 Pekka.Pessi@nokia.com * sofia-sip/heap.h: fixed bug in heap##remove() If left kid was in heap but right was not, left kid was ignored. Wed Jul 4 18:51:08 EDT 2007 Pekka.Pessi@nokia.com * smoothsort.c: added Wed Jul 4 18:51:34 EDT 2007 Pekka.Pessi@nokia.com * heap.h: using su_smoothsort() Fri Jul 6 10:20:27 EDT 2007 Pekka.Pessi@nokia.com * smoothsort.c: added Wed Sep 19 17:40:30 EDT 2007 Pekka.Pessi@nokia.com * msg_parser.awk: generate two parser tables, default and extended Wed Sep 19 18:39:45 EDT 2007 Pekka.Pessi@nokia.com * msg_parser.awk: just generate list of extra headers Allocate extended parser dynamically. Wed Sep 19 18:59:59 EDT 2007 Pekka.Pessi@nokia.com * sip: added Remote-Party-ID, P-Asserted-Identity, P-Preferred-Identity Added functions sip_update_default_mclass() and sip_extend_mclass() for handling the extended parser. Note that Reply-To and Alert-Info are only available with the extended parser. Wed Sep 19 19:05:44 EDT 2007 Pekka.Pessi@nokia.com * RELEASE: updated Thu Sep 20 13:38:59 EDT 2007 Pekka.Pessi@nokia.com * sip: updated documentation Thu Sep 20 14:17:28 EDT 2007 Pekka.Pessi@nokia.com * docs/conformance.docs: updated Mon Oct 1 10:11:14 EDT 2007 Pekka.Pessi@nokia.com * tport_tag.c: re-enabled tptag_trusted Thu Oct 4 09:21:07 EDT 2007 Pekka.Pessi@nokia.com * su_osx_runloop.c: moved virtual function table after struct definition Preparing for su_port_vtable_t refactoring. Thu Oct 4 10:22:03 EDT 2007 Pekka.Pessi@nokia.com * su_source.c: refactored initialization/deinitialization Fri Oct 5 04:58:18 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * sip_extra.c: fixed prototypes with isize_t Fri Oct 5 04:58:45 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * test_nta_api.c: removed warnings about signedness Fri Oct 5 04:59:02 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * test_nua_params.c: removed warnings about constness Fri Oct 5 07:20:26 EDT 2007 Pekka Pessi <first.lastname@nokia.com> * su_port.h, su_root.c: cleaned argument checking The su_root_*() and su_port_*() functions now check their arguments once and do not assert() with NULL arguments. The sur_task->sut_port should always be valid while su_root_t is alive. Fri Oct 5 07:22:09 EDT 2007 Pekka Pessi <first.lastname@nokia.com> * su: added su_root_obtain(), su_root_release() and su_root_has_thread() When root is created with su_root_create() or cloned with su_clone_start(), the resulting root is obtained by the calling or created thread, respectively. The root can be released with su_root_release() and another thread can obtain it. The function su_root_has_thread() can be used to check if a thread has obtained or released the root. Implementation upgraded the su_port_own_thread() method as su_port_thread(). Fri Oct 5 07:28:10 EDT 2007 Pekka Pessi <first.lastname@nokia.com> * su_port.h: removed su_port_threadsafe() and su_port_yield() methods su_port_wait_events() replaces su_port_yield(). Fri Oct 5 13:26:04 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * msg_parser.awk: not extending header structure unless needed. Removed gawk-ish /* comments */. Fri Oct 5 14:32:25 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * run_test_su: removed GNUisms Fri Oct 5 14:32:47 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Makefile.am: removed implicit check target test_urlmap Fri Oct 5 14:22:32 EDT 2007 Pekka Pessi <first.lastname@nokia.com> * torture_sresolv.c: use CLOCK_REALTIME if no CLOCK_PROCESS_CPUTIME_ID available Casting timespec tv_sec to unsigned long. Fri Oct * nua_s added handling nua_prack() Thanks to Fabio Margarido for the patch. Mon Oct 8 10:24:35 EDT 2007 Pekka.Pessi@nokia.com * test_nua: added test for sf.net bug #1803686 Mon Oct 8 08:15:23 EDT 2007 Pekka.Pessi@nokia.com * RELEASE: updated. Mon Oct 8 09:30:36 EDT 2007 Pekka.Pessi@nokia.com * nua_stack: added handling nua_prack() Thanks to Fabio Margarido for the patch. Mon Oct 8 10:24:35 EDT 2007 Pekka.Pessi@nokia.com * test_nua: added test for sf.net bug #1803686 Mon Oct 8 10:26:31 EDT 2007 Pekka.Pessi@nokia.com * nua: added test for nua_prack() (sf.net bug #1804248) Avoid sending nua_i_state after nua_prack() if no SDP O/A is happening, too. Mon Oct 8 10:32:04 EDT 2007 Mikhail Zabaluev <mikhail.zabaluev@nokia.com> * su_source.c: don t leak the wait arrays Mon Oct 8 10:37:11 EDT 2007 Pekka.Pessi@nokia.com * RELEASE: updated Wed Oct 10 11:55:21 EDT 2007 Pekka.Pessi@nokia.com * sip_parser.c: silenced warning about extra const in sip_extend_mclass() Wed Oct 10 11:57:08 EDT 2007 Pekka.Pessi@nokia.com * nta_tag.c: updated tag documentation Wed Oct 10 13:16:40 EDT 2007 Pekka.Pessi@nokia.com * nua: fix logging crash if outbound used with application contact Silenced warnings. Wed Oct 10 13:30:45 EDT 2007 Pekka.Pessi@nokia.com * msg_parser.awk: removed extra "const" Wed Oct 10 13:31:45 EDT 2007 Pekka.Pessi@nokia.com * Makefile.am's: fixed distclean of documentation git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5840 d0543943-73ff-0310-b7d9-9358b9ac24b2
2007-10-11 14:16:59 +00:00
/**@ingroup su_alloc
* @CFILE su_alloc.c Home-based memory management.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>.
*
* @date Created: Thu Aug 19 01:12:25 1999 ppessi
*/
#include <sofia-sip/su_config.h>
#include "sofia-sip/su_alloc.h"
#include "sofia-sip/su_alloc_stat.h"
#include "sofia-sip/su_errno.h"
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <memory.h>
#include <limits.h>
#include <assert.h>
int (*_su_home_locker)(void *mutex);
int (*_su_home_unlocker)(void *mutex);
int (*_su_home_mutex_locker)(void *mutex);
int (*_su_home_mutex_trylocker)(void *mutex);
int (*_su_home_mutex_unlocker)(void *mutex);
void (*_su_home_destroy_mutexes)(void *mutex);
#define MEMLOCK(h) \
((void)((h) && (h)->suh_lock ? _su_home_locker((h)->suh_lock) : 0), (h)->suh_blocks)
#define UNLOCK(h) ((void)((h) && (h)->suh_lock ? _su_home_unlocker((h)->suh_lock) : 0), NULL)
#ifdef NDEBUG
#define MEMCHECK 0
#define MEMCHECK_EXTRA 0
#elif !defined(MEMCHECK)
/* Default settings for valgrinding */
#define MEMCHECK 1
#define MEMCHECK_EXTRA 0
#elif !defined(MEMCHECK_EXTRA)
#define MEMCHECK_EXTRA sizeof (size_t)
#endif
enum {
SUB_N = 31, /**< Initial size */
SUB_N_AUTO = 7, /**< Initial size for autohome */
SUB_P = 29 /**< Secondary probe.
* Secondary probe must be relative prime
* with all sub_n values */
};
#define ALIGNMENT (8)
#define ALIGN(n) (size_t)(((n) + (ALIGNMENT - 1)) & (size_t)~(ALIGNMENT - 1))
#define SIZEBITS (sizeof (unsigned) * 8 - 1)
typedef struct {
unsigned sua_size:SIZEBITS; /**< Size of the block */
unsigned sua_home:1; /**< Is this another home? */
unsigned :0;
void *sua_data; /**< Data pointer */
} su_alloc_t;
struct su_block_s {
su_home_t *sub_parent; /**< Parent home */
char *sub_preload; /**< Preload area */
su_home_stat_t *sub_stats; /**< Statistics.. */
void (*sub_destructor)(void *); /**< Destructor function */
size_t sub_ref; /**< Reference count */
#define REF_MAX SIZE_MAX
size_t sub_used; /**< Number of blocks allocated */
size_t sub_n; /**< Size of hash table */
unsigned sub_prsize:16; /**< Preload size */
unsigned sub_prused:16; /**< Used from preload */
unsigned sub_hauto:1; /**< "Home" is not from malloc */
unsigned sub_auto:1; /**< struct su_block_s is not from malloc */
unsigned sub_preauto:1; /**< Preload is not from malloc */
unsigned sub_auto_all:1; /**< Everything is from stack! */
unsigned :0;
su_alloc_t sub_nodes[SUB_N]; /**< Pointers to data/lower blocks */
};
static void su_home_check_blocks(su_block_t const *b);
static void su_home_stats_alloc(su_block_t *, void *p, void *preload,
size_t size, int zero);
static void su_home_stats_free(su_block_t *sub, void *p, void *preload,
unsigned size);
static void _su_home_deinit(su_home_t *home);
#define SU_ALLOC_STATS 1
#if SU_ALLOC_STATS
size_t count_su_block_find, count_su_block_find_loop;
size_t size_su_block_find, used_su_block_find;
size_t max_size_su_block_find, max_used_su_block_find;
size_t su_block_find_collision, su_block_find_collision_used,
su_block_find_collision_size;
#endif
su_inline su_alloc_t *su_block_find(su_block_t *b, void const *p)
{
size_t h, h0, probe;
#if SU_ALLOC_STATS
size_t collision = 0;
count_su_block_find++;
size_su_block_find += b->sub_n;
used_su_block_find += b->sub_used;
if (b->sub_n > max_size_su_block_find)
max_size_su_block_find = b->sub_n;
if (b->sub_used > max_used_su_block_find)
max_used_su_block_find = b->sub_used;
#endif
assert(p != NULL);
h = h0 = (size_t)((uintptr_t)p % b->sub_n);
probe = (b->sub_n > SUB_P) ? SUB_P : 1;
do {
if (b->sub_nodes[h].sua_data == p)
return &b->sub_nodes[h];
h += probe;
if (h >= b->sub_n)
h -= b->sub_n;
#if SU_ALLOC_STATS
if (++collision > su_block_find_collision)
su_block_find_collision = collision,
su_block_find_collision_used = b->sub_used,
su_block_find_collision_size = b->sub_n;
count_su_block_find_loop++;
#endif
} while (h != h0);
return NULL;
}
su_inline su_alloc_t *su_block_add(su_block_t *b, void *p)
{
size_t h, probe;
assert(p != NULL);
h = (size_t)((uintptr_t)p % b->sub_n);
probe = (b->sub_n > SUB_P) ? SUB_P : 1;
while (b->sub_nodes[h].sua_data) {
h += probe;
if (h >= b->sub_n)
h -= b->sub_n;
}
b->sub_used++;
b->sub_nodes[h].sua_data = p;
return &b->sub_nodes[h];
}
su_inline int su_is_preloaded(su_block_t const *sub, char *data)
{
return
sub->sub_preload &&
sub->sub_preload <= data &&
sub->sub_preload + sub->sub_prsize > data;
}
su_inline int su_alloc_check(su_block_t const *sub, su_alloc_t const *sua)
{
#if MEMCHECK_EXTRA
size_t size, term;
assert(sua);
if (sua) {
size = (size_t)sua->sua_size;
memcpy(&term, (char *)sua->sua_data + size, sizeof (term));
assert(size - term == 0);
return size - term == 0;
}
else
return 0;
#endif
return sua != NULL;
}
/** Allocate the block hash table.
*
* @internal
*
* Allocate a block hash table of @a n elements.
*
* @param home pointer to home object
* @param n number of buckets in hash table
*
* @return
* This function returns a pointer to the allocated hash table or
* NULL if an error occurred.
*/
su_inline su_block_t *su_hash_alloc(size_t n)
{
su_block_t *b = calloc(1, offsetof(su_block_t, sub_nodes[n]));
if (b) {
/* Implicit su_home_init(); */
b->sub_ref = 1;
b->sub_hauto = 1;
b->sub_n = n;
}
return b;
}
enum sub_zero { do_malloc, do_calloc, do_clone };
/** Allocate a memory block.
*
* @internal
*
* Precondition: locked home
*
* @param home home to allocate
* @param sub block structure used to allocate
* @param size
* @param zero if true, zero allocated block;
* if > 1, allocate a subhome
*
*/
static
void *sub_alloc(su_home_t *home,
su_block_t *sub,
size_t size,
enum sub_zero zero)
{
void *data, *preload = NULL;
assert (size < (((size_t)1) << SIZEBITS));
if (size >= ((size_t)1) << SIZEBITS)
return (void)(errno = ENOMEM), NULL;
if (sub == NULL || 3 * sub->sub_used > 2 * sub->sub_n) {
/* Resize the hash table */
size_t i, n, n2, used;
su_block_t *b2;
if (sub)
n = home->suh_blocks->sub_n, n2 = 4 * n + 3, used = sub->sub_used;
else
n = 0, n2 = SUB_N, used = 0;
#if 0
printf("su_alloc(home = %p): realloc block hash of size %d\n", home, n2);
#endif
if (!(b2 = su_hash_alloc(n2)))
return NULL;
for (i = 0; i < n; i++) {
if (sub->sub_nodes[i].sua_data)
su_block_add(b2, sub->sub_nodes[i].sua_data)[0] = sub->sub_nodes[i];
}
if (sub) {
b2->sub_parent = sub->sub_parent;
b2->sub_ref = sub->sub_ref;
b2->sub_preload = sub->sub_preload;
b2->sub_prsize = sub->sub_prsize;
b2->sub_prused = sub->sub_prused;
b2->sub_hauto = sub->sub_hauto;
b2->sub_preauto = sub->sub_preauto;
b2->sub_destructor = sub->sub_destructor;
/* auto_all is not copied! */
b2->sub_stats = sub->sub_stats;
}
home->suh_blocks = b2;
if (sub && !sub->sub_auto)
free(sub);
sub = b2;
}
if (size && sub && zero < do_clone &&
sub->sub_preload && size <= sub->sub_prsize) {
/* Use preloaded memory */
size_t prused = sub->sub_prused + size + MEMCHECK_EXTRA;
prused = ALIGN(prused);
if (prused <= sub->sub_prsize) {
preload = (char *)sub->sub_preload + sub->sub_prused;
sub->sub_prused = (unsigned)prused;
}
}
if (preload && zero)
data = memset(preload, 0, size);
else if (preload)
data = preload;
else if (zero)
data = calloc(1, size + MEMCHECK_EXTRA);
else
data = malloc(size + MEMCHECK_EXTRA);
if (data) {
su_alloc_t *sua;
#if MEMCHECK_EXTRA
size_t term = 0 - size;
memcpy((char *)data + size, &term, sizeof (term));
#endif
if (!preload)
sub->sub_auto_all = 0;
if (zero >= do_clone) {
/* Prepare cloned home */
su_home_t *subhome = data;
assert(preload == 0);
subhome->suh_blocks = su_hash_alloc(SUB_N);
if (!subhome->suh_blocks)
return (void)free(data), NULL;
subhome->suh_size = (unsigned)size;
subhome->suh_blocks->sub_parent = home;
subhome->suh_blocks->sub_hauto = 0;
}
/* OK, add the block to the hash table. */
sua = su_block_add(sub, data); assert(sua);
sua->sua_size = (unsigned)size;
sua->sua_home = zero > 1;
if (sub->sub_stats)
su_home_stats_alloc(sub, data, preload, size, zero);
}
return data;
}
/**Create a new su_home_t object.
*
* Create a home object used to collect multiple memory allocations under
* one handle. The memory allocations made using this home object is freed
* either when this home is destroyed.
*
* The maximum @a size of a home object is INT_MAX (2 gigabytes).
*
* @param size size of home object
*
* The memory home object allocated with su_home_new() can be reclaimed with
* su_home_unref().
*
* @return
* This function returns a pointer to an su_home_t object, or NULL upon
* an error.
*/
void *su_home_new(isize_t size)
{
su_home_t *home;
assert(size >= sizeof (*home));
if (size < sizeof (*home))
return (void)(errno = EINVAL), NULL;
else if (size > INT_MAX)
return (void)(errno = ENOMEM), NULL;
home = calloc(1, size);
if (home) {
home->suh_size = (int)size;
home->suh_blocks = su_hash_alloc(SUB_N);
if (home->suh_blocks)
home->suh_blocks->sub_hauto = 0;
else
free(home), home = NULL;
}
return home;
}
/** Create a new reference to a home object. */
void *su_home_ref(su_home_t const *home)
{
if (home) {
su_block_t *sub = MEMLOCK(home);
if (sub == NULL || sub->sub_ref == 0) {
assert(sub && sub->sub_ref != 0);
UNLOCK(home);
return NULL;
}
if (sub->sub_ref != REF_MAX)
sub->sub_ref++;
UNLOCK(home);
}
else
su_seterrno(EFAULT);
return (void *)home;
}
/** Set destructor function.
*
* The destructor function is called after the reference count of a
* #su_home_t object reaches zero or a home object is deinitialized, but
* before any of the memory areas within the home object are freed.
*
* @since New in @VERSION_1_12_4.
* Earlier versions had su_home_desctructor() (spelling).
*/
int su_home_destructor(su_home_t *home, void (*destructor)(void *))
{
int retval = -1;
if (home) {
su_block_t *sub = MEMLOCK(home);
if (sub && sub->sub_destructor == NULL) {
sub->sub_destructor = destructor;
retval = 0;
}
UNLOCK(home);
}
else
su_seterrno(EFAULT);
return retval;
}
#undef su_home_desctructor
/** Set destructor function.
*
* @deprecated The su_home_destructor() was added in @VERSION_1_12_4. The
* su_home_desctructor() is now defined as a macro expanding as
* su_home_destructor(). If you want to compile an application as binary
* compatible with earlier versions, you have to define su_home_desctructor
* as itself, e.g.,
* @code
* #define su_home_desctructor su_home_desctructor
* #include <sofia-sip/su_alloc.h>
* @endcode
*/
int su_home_desctructor(su_home_t *home, void (*destructor)(void *))
{
return su_home_destructor(home, destructor);
}
/**Unreference a su_home_t object.
*
* Decrements the reference count on home object and destroys and frees it
* and the memory allocations using it if the reference count reaches 0.
*
* @param home memory pool object to be unreferenced
*
* @retval 1 if object was freed
* @retval 0 if object is still alive
*/
int su_home_unref(su_home_t *home)
{
su_block_t *sub;
if (home == NULL)
return 0;
sub = MEMLOCK(home);
if (sub == NULL) {
/* Xyzzy */
return 0;
}
else if (sub->sub_ref == REF_MAX) {
UNLOCK(home);
return 0;
}
else if (--sub->sub_ref > 0) {
UNLOCK(home);
return 0;
}
else if (sub->sub_parent) {
su_home_t *parent = sub->sub_parent;
UNLOCK(home);
su_free(parent, home);
return 1;
}
else {
int hauto = sub->sub_hauto;
_su_home_deinit(home);
if (!hauto)
free(home);
/* UNLOCK(home); */
return 1;
}
}
/** Return reference count of home. */
size_t su_home_refcount(su_home_t *home)
{
size_t count = 0;
if (home) {
su_block_t *sub = MEMLOCK(home);
if (sub)
count = sub->sub_ref;
UNLOCK(home);
}
return count;
}
/**Clone a su_home_t object.
*
* Clone a secondary home object used to collect multiple memoryf
* allocations under one handle. The memory is freed either when the cloned
* home is destroyed or when the parent home is destroyed.
*
* An independent
* home object is created if NULL is passed as @a parent argument.
*
* @param parent a parent object (may be NULL)
* @param size size of home object
*
* The memory home object allocated with su_home_clone() can be freed with
* su_home_unref().
*
* @return
* This function returns a pointer to an su_home_t object, or NULL upon
* an error.
*/
void *su_home_clone(su_home_t *parent, isize_t size)
{
su_home_t *home;
assert(size >= sizeof (*home));
if (size < sizeof (*home))
return (void)(errno = EINVAL), NULL;
else if (size > INT_MAX)
return (void)(errno = ENOMEM), NULL;
if (parent) {
su_block_t *sub = MEMLOCK(parent);
home = sub_alloc(parent, sub, size, 2);
UNLOCK(parent);
}
else {
home = su_home_new(size);
}
return home;
}
/** Return true if home is a clone. */
int su_home_has_parent(su_home_t const *home)
{
return home && !home->suh_lock &&
home->suh_blocks && home->suh_blocks->sub_parent;
}
/** Allocate a memory block.
*
* Allocates a memory block of a given @a size.
*
* If @a home is NULL, this function behaves exactly like malloc().
*
* @param home pointer to home object
* @param size size of the memory block to be allocated
*
* @return
* This function returns a pointer to the allocated memory block or
* NULL if an error occurred.
*/
void *su_alloc(su_home_t *home, isize_t size)
{
void *data;
if (home) {
data = sub_alloc(home, MEMLOCK(home), size, 0);
UNLOCK(home);
}
else
data = malloc(size);
return data;
}
/**Free a memory block.
*
* Frees a single memory block. The @a home must be the owner of the memory
* block (usually the memory home used to allocate the memory block, or NULL
* if no home was used).
*
* @param home pointer to home object
* @param data pointer to the memory block to be freed
*/
void su_free(su_home_t *home, void *data)
{
if (!data)
return;
if (home) {
su_alloc_t *allocation;
su_block_t *sub = MEMLOCK(home);
assert(sub);
allocation = su_block_find(sub, data);
assert(allocation);
if (su_alloc_check(sub, allocation)) {
void *preloaded = NULL;
/* Is this preloaded data? */
if (su_is_preloaded(sub, data))
preloaded = data;
if (sub->sub_stats)
su_home_stats_free(sub, data, preloaded, allocation->sua_size);
if (allocation->sua_home) {
su_home_t *subhome = data;
su_block_t *sub = MEMLOCK(subhome);
assert(sub->sub_ref != REF_MAX);
/* assert(sub->sub_ref > 0); */
sub->sub_ref = 0; /* Zap all references */
_su_home_deinit(subhome);
}
#if MEMCHECK != 0
memset(data, 0xaa, (size_t)allocation->sua_size);
#endif
memset(allocation, 0, sizeof (*allocation));
sub->sub_used--;
if (preloaded)
data = NULL;
}
UNLOCK(home);
}
free(data);
}
/** Check home consistency.
*
* Ensures that the home structure and all memory blocks allocated through
* it are consistent. It can be used to catch memory allocation and usage
* errors.
*
* @param home Pointer to a memory home.
*/
void su_home_check(su_home_t const *home)
{
#if MEMCHECK != 0
su_block_t const *b = MEMLOCK(home);
su_home_check_blocks(b);
UNLOCK(home);
#endif
}
/** Check home blocks. */
static
void su_home_check_blocks(su_block_t const *b)
{
#if MEMCHECK != 0
if (b) {
size_t i, used;
assert(b->sub_used <= b->sub_n);
for (i = 0, used = 0; i < b->sub_n; i++)
if (b->sub_nodes[i].sua_data) {
su_alloc_check(b, &b->sub_nodes[i]), used++;
if (b->sub_nodes[i].sua_home)
su_home_check((su_home_t *)b->sub_nodes[i].sua_data);
}
assert(used == b->sub_used);
}
#endif
}
/**
* Create an su_home_t object.
*
* Creates a home object. A home object is used to collect multiple memory
* allocations, so that they all can be freed by calling su_home_unref().
*
* @return This function returns a pointer to an #su_home_t object, or
* NULL upon an error.
*/
su_home_t *su_home_create(void)
{
return su_home_new(sizeof(su_home_t));
}
/** Destroy a home object
*
* Frees all memory blocks associated with a home object. Note that the home
* object structure is not freed.
*
* @param home pointer to a home object
*
* @deprecated
* su_home_destroy() is included for backwards compatibility only. Use
* su_home_unref() instead of su_home_destroy().
*/
void su_home_destroy(su_home_t *home)
{
if (MEMLOCK(home)) {
assert(home->suh_blocks);
assert(home->suh_blocks->sub_ref == 1);
if (!home->suh_blocks->sub_hauto)
/* should warn user */;
home->suh_blocks->sub_hauto = 1;
_su_home_deinit(home);
/* UNLOCK(home); */
}
}
/** Initialize an su_home_t struct.
*
* Initializes an su_home_t structure. It can be used when the home
* structure is allocated from stack or when the home structure is part of
* an another object.
*
* @param home pointer to home object
*
* @retval 0 when successful
* @retval -1 upon an error.
*
* @sa SU_HOME_INIT(), su_home_deinit(), su_home_new(), su_home_clone()
merge with sofia darcs trunk: Fri Oct 12 08:42:17 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Makefile.am: fixed ordering of SUBDIRS Fri Oct 12 13:32:02 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32/utils/stunc.dsp: fixed include paths Fri Oct 12 13:32:19 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32/tests/torture_su_root: fixed include paths Fri Oct 12 13:32:52 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32: added missing files from Makefile.am, .dsp, vproj Fri Oct 12 13:33:42 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32/build_sources.cmd: added extra headers to sip_tag.c and sip_parser_table.c Fri Oct 12 13:37:00 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32/check.cmd: added option -a to relevant tests. Optionally check Release build. Fri Oct 12 13:37:25 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * url.h: silenced warning on URL_INIT_AS() Fri Oct 12 13:37:43 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * tstdef.h: silenced warnings on TEST_M() Fri Oct 12 13:38:15 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta_internal.h, nua_params.c: fixed NTATAG_UDP_MTU() type Fri Oct 12 13:39:06 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * test_class.h: fixed test_auth_class, test_numeric_class declaration Fri Oct 12 13:39:51 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Fixed various tests on win32. Fri Oct 12 13:39:58 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * sip_basic.c: removed dead code Fri Oct 12 14:38:02 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nea_server.c: avoid raporting un-SUBSCRIBE twice Fri Oct 12 14:38:31 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * test_sip_events.c: checking some nua_i_notifier/nua_i_subscriber events Fri Oct 12 14:38:42 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged Release candidate 2 for 1.12.7 Mon Oct 15 04:03:22 EDT 2007 Pekka.Pessi@nokia.com * configure.ac, RELEASE: version 1.12.7 Mon Oct 15 08:27:13 EDT 2007 Pekka.Pessi@nokia.com * open_c: included in the dist Tue Oct 16 08:07:46 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua: Open C fixes Wed Oct 17 06:50:11 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua.docs: replace reference to nua_cli.c with sofsip_cli Wed Oct 17 08:43:11 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged rel-sofia-sip-1_12_7 Wed Oct 17 08:43:15 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged 1.12.7 Wed Oct 17 11:01:12 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * libsofia-sip-ua/su/Makefile.am: fixed problem with automake 1.9 Wed Oct 17 11:13:15 EDT 2007 Pekka.Pessi@nokia.com * configure.ac, RELEASE: opened tree for development Tue Oct 23 10:45:17 EDT 2007 Pekka.Pessi@nokia.com * su_alloc.c: fixed su_home_init() (not initializing pointer to mutexes) Thu Oct 25 13:15:45 EDT 2007 Pekka.Pessi@nokia.com * nua_notifier.c: updated nua_i_subscribe, nua_notify() and nua_r_notify documentation Wed Nov 7 07:58:08 EST 2007 Pekka.Pessi@nokia.com * sofia-sip/htable2.h: fixed HTABLE_PROTOS2() git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6219 d0543943-73ff-0310-b7d9-9358b9ac24b2
2007-11-12 16:04:47 +00:00
*
* @bug
* Prior to @VERSION_1_12_8 the su_home_t structure should have been
* initialized with SU_HOME_INIT() or otherwise zeroed before calling
* su_home_init().
*/
int su_home_init(su_home_t *home)
{
su_block_t *sub;
if (home == NULL)
return -1;
home->suh_blocks = sub = su_hash_alloc(SUB_N);
merge with sofia darcs trunk: Fri Oct 12 08:42:17 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Makefile.am: fixed ordering of SUBDIRS Fri Oct 12 13:32:02 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32/utils/stunc.dsp: fixed include paths Fri Oct 12 13:32:19 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32/tests/torture_su_root: fixed include paths Fri Oct 12 13:32:52 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32: added missing files from Makefile.am, .dsp, vproj Fri Oct 12 13:33:42 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32/build_sources.cmd: added extra headers to sip_tag.c and sip_parser_table.c Fri Oct 12 13:37:00 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32/check.cmd: added option -a to relevant tests. Optionally check Release build. Fri Oct 12 13:37:25 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * url.h: silenced warning on URL_INIT_AS() Fri Oct 12 13:37:43 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * tstdef.h: silenced warnings on TEST_M() Fri Oct 12 13:38:15 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta_internal.h, nua_params.c: fixed NTATAG_UDP_MTU() type Fri Oct 12 13:39:06 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * test_class.h: fixed test_auth_class, test_numeric_class declaration Fri Oct 12 13:39:51 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Fixed various tests on win32. Fri Oct 12 13:39:58 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * sip_basic.c: removed dead code Fri Oct 12 14:38:02 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nea_server.c: avoid raporting un-SUBSCRIBE twice Fri Oct 12 14:38:31 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * test_sip_events.c: checking some nua_i_notifier/nua_i_subscriber events Fri Oct 12 14:38:42 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged Release candidate 2 for 1.12.7 Mon Oct 15 04:03:22 EDT 2007 Pekka.Pessi@nokia.com * configure.ac, RELEASE: version 1.12.7 Mon Oct 15 08:27:13 EDT 2007 Pekka.Pessi@nokia.com * open_c: included in the dist Tue Oct 16 08:07:46 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua: Open C fixes Wed Oct 17 06:50:11 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua.docs: replace reference to nua_cli.c with sofsip_cli Wed Oct 17 08:43:11 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged rel-sofia-sip-1_12_7 Wed Oct 17 08:43:15 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged 1.12.7 Wed Oct 17 11:01:12 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * libsofia-sip-ua/su/Makefile.am: fixed problem with automake 1.9 Wed Oct 17 11:13:15 EDT 2007 Pekka.Pessi@nokia.com * configure.ac, RELEASE: opened tree for development Tue Oct 23 10:45:17 EDT 2007 Pekka.Pessi@nokia.com * su_alloc.c: fixed su_home_init() (not initializing pointer to mutexes) Thu Oct 25 13:15:45 EDT 2007 Pekka.Pessi@nokia.com * nua_notifier.c: updated nua_i_subscribe, nua_notify() and nua_r_notify documentation Wed Nov 7 07:58:08 EST 2007 Pekka.Pessi@nokia.com * sofia-sip/htable2.h: fixed HTABLE_PROTOS2() git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6219 d0543943-73ff-0310-b7d9-9358b9ac24b2
2007-11-12 16:04:47 +00:00
home->suh_lock = NULL;
if (!sub)
return -1;
return 0;
}
#define safe_free(it) if (it) { free(it); it = NULL; }
/** Internal deinitialization */
static
void _su_home_deinit(su_home_t *home)
{
if (home->suh_blocks) {
size_t i;
su_block_t *b;
if (home->suh_blocks->sub_destructor) {
void (*destructor)(void *) = home->suh_blocks->sub_destructor;
home->suh_blocks->sub_destructor = NULL;
destructor(home);
}
b = home->suh_blocks;
su_home_check_blocks(b);
for (i = 0; i < b->sub_n; i++) {
if (b->sub_nodes[i].sua_data) {
if (b->sub_nodes[i].sua_home) {
su_home_t *subhome = b->sub_nodes[i].sua_data;
su_block_t *subb = MEMLOCK(subhome);
assert(subb); assert(subb->sub_ref >= 1);
#if 0
if (subb->sub_ref > 0)
SU_DEBUG_7(("su_home_unref: subhome %p with destructor %p has still %u refs\n",
subhome, subb->sub_destructor, subb->sub_ref));
#endif
subb->sub_ref = 0; /* zap them all */
_su_home_deinit(subhome);
}
else if (su_is_preloaded(b, b->sub_nodes[i].sua_data))
continue;
safe_free(b->sub_nodes[i].sua_data);
}
}
if (b->sub_preload && !b->sub_preauto)
safe_free(b->sub_preload);
if (b->sub_stats)
safe_free(b->sub_stats);
if (!b->sub_auto)
safe_free(b);
home->suh_blocks = NULL;
if (home->suh_lock)
_su_home_destroy_mutexes(home->suh_lock);
}
home->suh_lock = NULL;
}
/** Free memory blocks allocated through home.
*
* Frees the memory blocks associated with the home object allocated. It
* does not free the home object itself. Use su_home_unref() to free the
* home object.
*
* @param home pointer to home object
*
* @sa su_home_init()
*/
void su_home_deinit(su_home_t *home)
{
if (MEMLOCK(home)) {
assert(home->suh_blocks);
assert(home->suh_blocks->sub_ref == 1);
assert(home->suh_blocks->sub_hauto);
_su_home_deinit(home);
/* UNLOCK(home); */
}
}
/**Move allocations from a su_home_t object to another.
*
* Moves allocations made through the @a src home object under the @a dst
* home object. It is handy, for example, if an operation allocates some
* number of blocks that should be freed upon an error. It uses a temporary
* home and moves the blocks from temporary to a proper home when
* successful, but frees the temporary home upon an error.
*
* If @a src has destructor, it is called before starting to move.
*
* @param dst destination home
* @param src source home
*
* @retval 0 if succesful
* @retval -1 upon an error
*/
int su_home_move(su_home_t *dst, su_home_t *src)
{
size_t i, n, n2, used;
su_block_t *s, *d, *d2;
if (src == NULL || dst == src)
return 0;
if (dst) {
s = MEMLOCK(src); d = MEMLOCK(dst);
if (s && s->sub_n) {
if (s->sub_destructor) {
void (*destructor)(void *) = s->sub_destructor;
s->sub_destructor = NULL;
destructor(src);
}
if (d)
used = s->sub_used + d->sub_used;
else
used = s->sub_used;
if ((used && d == NULL) || 3 * used > 2 * d->sub_n) {
if (d)
for (n = n2 = d->sub_n; 3 * used > 2 * n2; n2 = 4 * n2 + 3)
;
else
n = 0, n2 = s->sub_n;
if (!(d2 = su_hash_alloc(n2))) {
UNLOCK(dst); UNLOCK(src);
return -1;
}
dst->suh_blocks = d2;
for (i = 0; i < n; i++)
if (d->sub_nodes[i].sua_data)
su_block_add(d2, d->sub_nodes[i].sua_data)[0] = d->sub_nodes[i];
if (d) {
d2->sub_parent = d->sub_parent;
d2->sub_ref = d->sub_ref;
d2->sub_preload = d->sub_preload;
d2->sub_prsize = d->sub_prsize;
d2->sub_prused = d->sub_prused;
d2->sub_preauto = d->sub_preauto;
d2->sub_stats = d->sub_stats;
}
if (d && !d->sub_auto)
free(d);
d = d2;
}
if ((n = s->sub_n)) {
for (i = 0; i < n; i++)
if (s->sub_nodes[i].sua_data) {
su_block_add(d, s->sub_nodes[i].sua_data)[0] = s->sub_nodes[i];
}
s->sub_used = 0;
memset(s->sub_nodes, 0, n * sizeof (s->sub_nodes[0]));
}
if (s->sub_stats) {
}
}
UNLOCK(dst); UNLOCK(src);
}
else {
s = MEMLOCK(src);
if (s && s->sub_used) {
s->sub_used = 0;
memset(s->sub_nodes, 0, s->sub_n * sizeof (s->sub_nodes[0]));
}
UNLOCK(src);
}
return 0;
}
/** Preload a memory home.
*
* The function su_home_preload() preloads a memory home.
*/
void su_home_preload(su_home_t *home, isize_t n, isize_t isize)
{
su_block_t *sub;
if (home == NULL)
return;
if (home->suh_blocks == NULL)
su_home_init(home);
sub = MEMLOCK(home);
if (!sub->sub_preload) {
size_t size;
void *preload;
size = n * ALIGN(isize);
if (size > 65535) /* We have 16 bits... */
size = 65535 & (ALIGNMENT - 1);
preload = malloc(size);
home->suh_blocks->sub_preload = preload;
home->suh_blocks->sub_prsize = (unsigned)size;
}
UNLOCK(home);
}
/** Preload a memory home from stack.
*
* Initializes a memory home using an area allocated from stack. Poor man's
* alloca().
*/
su_home_t *su_home_auto(void *area, isize_t size)
{
su_home_t *home;
su_block_t *sub;
size_t homesize = ALIGN(sizeof *home);
size_t subsize = ALIGN(offsetof(su_block_t, sub_nodes[SUB_N_AUTO]));
size_t prepsize;
char *p = area;
prepsize = homesize + subsize + (ALIGN((intptr_t)p) - (intptr_t)p);
if (area == NULL || size < prepsize)
return NULL;
if (size > INT_MAX)
size = INT_MAX;
home = memset(p, 0, homesize);
home->suh_size = (int)size;
sub = memset(p + homesize, 0, subsize);
home->suh_blocks = sub;
if (size > prepsize + 65535)
size = prepsize + 65535;
sub->sub_n = SUB_N_AUTO;
sub->sub_ref = 1;
sub->sub_preload = p + prepsize;
sub->sub_prsize = (unsigned)(size - prepsize);
sub->sub_hauto = 1;
sub->sub_auto = 1;
sub->sub_preauto = 1;
sub->sub_auto_all = 1;
return home;
}
/** Reallocate a memory block.
*
* Allocates a memory block of @a size bytes.
* It copies the old block contents to the new block and frees the old
* block.
*
* If @a home is NULL, this function behaves exactly like realloc().
*
* @param home pointer to memory pool object
* @param data pointer to old memory block
* @param size size of the memory block to be allocated
*
* @return
* A pointer to the allocated memory block or
* NULL if an error occurred.
*/
void *su_realloc(su_home_t *home, void *data, isize_t size)
{
void *ndata;
su_alloc_t *sua;
su_block_t *sub;
size_t p;
size_t term = 0 - size;
if (!home)
return realloc(data, size);
if (size == 0) {
if (data)
su_free(home, data);
return NULL;
}
sub = MEMLOCK(home);
if (!data) {
data = sub_alloc(home, sub, size, 0);
UNLOCK(home);
return data;
}
sua = su_block_find(sub, data);
if (!su_alloc_check(sub, sua))
return UNLOCK(home);
assert(!sua->sua_home);
if (sua->sua_home)
return UNLOCK(home);
if (!su_is_preloaded(sub, data)) {
ndata = realloc(data, size + MEMCHECK_EXTRA);
if (ndata) {
if (sub->sub_stats) {
su_home_stats_free(sub, data, 0, sua->sua_size);
su_home_stats_alloc(sub, data, 0, size, 1);
}
#if MEMCHECK_EXTRA
memcpy((char *)ndata + size, &term, sizeof (term));
#else
(void)term;
#endif
memset(sua, 0, sizeof *sua);
sub->sub_used--;
su_block_add(sub, ndata)->sua_size = (unsigned)size;
}
UNLOCK(home);
return ndata;
}
p = (char *)data - home->suh_blocks->sub_preload;
p += sua->sua_size + MEMCHECK_EXTRA;
p = ALIGN(p);
if (p == sub->sub_prused) {
size_t p2 = (char *)data - sub->sub_preload + size + MEMCHECK_EXTRA;
p2 = ALIGN(p2);
if (p2 <= sub->sub_prsize) {
/* Extend/reduce existing preload */
if (sub->sub_stats) {
su_home_stats_free(sub, data, data, sua->sua_size);
su_home_stats_alloc(sub, data, data, size, 0);
}
sub->sub_prused = (unsigned)p2;
sua->sua_size = (unsigned)size;
#if MEMCHECK_EXTRA
memcpy((char *)data + size, &term, sizeof (term));
#endif
UNLOCK(home);
return data;
}
}
else if (size < (size_t)sua->sua_size) {
/* Reduce existing preload */
if (sub->sub_stats) {
su_home_stats_free(sub, data, data, sua->sua_size);
su_home_stats_alloc(sub, data, data, size, 0);
}
#if MEMCHECK_EXTRA
memcpy((char *)data + size, &term, sizeof (term));
#endif
sua->sua_size = (unsigned)size;
UNLOCK(home);
return data;
}
ndata = malloc(size + MEMCHECK_EXTRA);
if (ndata) {
if (p == sub->sub_prused) {
/* Free preload */
sub->sub_prused = (char *)data - home->suh_blocks->sub_preload;
if (sub->sub_stats)
su_home_stats_free(sub, data, data, sua->sua_size);
}
memcpy(ndata, data,
(size_t)sua->sua_size < size
? (size_t)sua->sua_size
: size);
#if MEMCHECK_EXTRA
memcpy((char *)ndata + size, &term, sizeof (term));
#endif
if (sub->sub_stats)
su_home_stats_alloc(sub, data, 0, size, 1);
memset(sua, 0, sizeof *sua); sub->sub_used--;
su_block_add(sub, ndata)->sua_size = (unsigned)size;
}
UNLOCK(home);
return ndata;
}
/**Check if a memory block has been allocated from the @a home.
*
* Check if the given memory block has been allocated from the home.
*
* @param home pointer to memory pool object
* @param memory ponter to memory block
*
* @retval 1 if @a memory has been allocated from @a home.
* @retval 0 otherwise
*
* @since New in @VERSION_1_12_4.
*/
int su_in_home(su_home_t *home, void const *memory)
{
su_alloc_t *sua;
su_block_t *sub;
int retval = 0;
if (!home || !memory)
return 0;
sub = MEMLOCK(home);
if (sub) {
sua = su_block_find(sub, memory);
retval = su_alloc_check(sub, sua);
UNLOCK(home);
}
return retval;
}
/**Allocate and zero a memory block.
*
* Allocates a memory block with a given size from
* given memory home @a home and zeroes the allocated block.
*
* @param home pointer to memory pool object
* @param size size of the memory block
*
* @note The memory home pointer @a home may be @c NULL. In that case, the
* allocated memory block is not associated with any memory home, and it
* must be freed by calling su_free() or free().
*
* @return
* The function su_zalloc() returns a pointer to the allocated memory block,
* or NULL upon an error.
*/
void *su_zalloc(su_home_t *home, isize_t size)
{
void *data;
assert (size >= 0);
if (home) {
data = sub_alloc(home, MEMLOCK(home), size, 1);
UNLOCK(home);
}
else
data = calloc(1, size);
return data;
}
/** Allocate a structure
*
* Allocates a structure with a given size, zeros
* it, and initializes the size field to the given size. The size field
* is an int at the beginning of the structure. Note that it has type of int.
*
* @param home pointer to memory pool object
* @param size size of the structure
*
* @par Example
* The structure is defined and allocated as follows:
* @code
* struct test {
* int tst_size;
* char *tst_name;
* void *tst_ptr[3];
* };
*
* struct test *t;
* ...
* t = su_salloc(home, sizeof (*t));
* assert(t && t->t_size == sizeof (*t));
*
* @endcode
* After calling su_salloc() we get a pointer t to a struct test,
* initialized to zero except the tst_size field, which is initialized to
* sizeof (*t).
*
* @return A pointer to the allocated structure, or NULL upon an error.
*/
void *su_salloc(su_home_t *home, isize_t size)
{
struct { int size; } *retval;
if (size < sizeof (*retval))
size = sizeof (*retval);
if (size > INT_MAX)
return (void)(errno = ENOMEM), NULL;
if (home) {
retval = sub_alloc(home, MEMLOCK(home), size, 1);
UNLOCK(home);
}
else
retval = calloc(1, size);
if (retval)
retval->size = (int)size;
return retval;
}
/** Check if a memory home is threadsafe */
int su_home_is_threadsafe(su_home_t const *home)
{
return home && home->suh_lock;
}
/** Increase refcount and obtain exclusive lock on home.
*
* @note The #su_home_t structure must be created with su_home_new() or
* su_home_clone(), or initialized with su_home_init() before using this
* function.
*
* In order to enable actual locking, use su_home_threadsafe(), too.
* Otherwise the su_home_mutex_lock() will just increase the reference
* count.
*/
int su_home_mutex_lock(su_home_t *home)
{
int error;
if (home == NULL)
return su_seterrno(EFAULT);
if (home->suh_blocks == NULL || !su_home_ref(home))
return su_seterrno(EINVAL); /* Uninitialized home */
if (!home->suh_lock)
return 0; /* No-op */
error = _su_home_mutex_locker(home->suh_lock);
if (error)
return su_seterrno(error);
return 0;
}
merge to sofia sip darcs tree. Includes multiple fixes and several merges of changes from the freeswitch tree back to darcs as follows: Mon Nov 19 22:05:07 EST 2007 Pekka Pessi <first.lastname@nokia.com> * test_htable2.c: define struct before using it in prototypes Fri Jan 11 09:12:01 EST 2008 Bernhard Suttner <suttner at comdasys.com> * Using # in SOATAG_HOLD to set media as inactive instead of sendonly Fri Jan 11 09:15:18 EST 2008 Pekka.Pessi@nokia.com * soa_tag.c: documented SOATAG_HOLD() inactive mode Fri Jan 11 09:28:46 EST 2008 Pekka.Pessi@nokia.com * su_addrinfo.c: if su_getaddrinfo() service is NULL, try both with "0" and NULL Fri Jan 11 09:30:23 EST 2008 Pekka.Pessi@nokia.com * Makefile.am: added tests to DIST_SUBDIRS Fri Jan 11 12:11:12 EST 2008 Pekka.Pessi@nokia.com * nta.c: NetModule hack re-prioritizing SRV records Original hack by Stefan Leuenberger <Stefan.Leuenberger@netmodule.com>. The hack reprioritizes the SRV records used with transaction in case a server refuses connection or it does not answer. Fri Jan 11 12:12:23 EST 2008 Pekka.Pessi@nokia.com * sres.c, sres_cache.c: NetModule hack for re-prioritizing SRV records Original hack by Stefan Leuenberger <Stefan.Leuenberger@netmodule.com>. The hack reprioritizes the SRV records used with transaction in case a server refuses connection or it does not answer. New functions sres_cache_set_srv_priority() and sres_set_cached_srv_priority(). Fri Jan 11 12:15:19 EST 2008 Pekka.Pessi@nokia.com * Makefile.am: fixed dist target Fri Jan 11 12:19:33 EST 2008 Pekka.Pessi@nokia.com * tport_internal.h: grammar in doc Mon Jan 14 06:59:17 EST 2008 Pekka.Pessi@nokia.com * su.h: IPv6 fix for Vista SDK Patch by Michael Jerris Wed Jan 16 13:20:47 EST 2008 Pekka.Pessi@nokia.com * nua: fix sf.net bug #1867753 (avoid duplicating initial route set) Thu Jan 17 07:48:10 EST 2008 Pekka.Pessi@nokia.com * sres.c, sres_cache.c: documented sres_set_cached_srv_priority(), sres_cache_set_srv_priority() Thu Jan 17 07:51:32 EST 2008 Pekka.Pessi@nokia.com * sofia-sip/su_wait.h, su_port.h, su_root.c: documented new functions and types for 1.12.8 Thu Jan 17 07:52:03 EST 2008 Pekka.Pessi@nokia.com * sofia-sip/htable2.h: marked new features for release 1.12.8 Thu Jan 17 07:52:33 EST 2008 Pekka.Pessi@nokia.com * su_alloc.c: marked new features for release 1.12.8. Thu Jan 17 07:53:01 EST 2008 Pekka.Pessi@nokia.com * AUTHORS: updated Thu Jan 17 07:53:21 EST 2008 Pekka.Pessi@nokia.com * RELEASE: added new features and bug fixes since 1.12.7 Thu Jan 17 07:55:18 EST 2008 Pekka.Pessi@nokia.com * libsofia-sip-ua/docs/Doxyfile.aliases: added @NEW_1_12_8 and @VERSION_1_12_8 Thu Jan 17 09:48:48 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * autogen.sh: use automake 1.9 unless otherwise specified Thu Jan 17 11:40:46 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * soa_static.c: cleaned inactive hold, added tests Thu Jan 17 11:41:54 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * Makefile.am: added hide_emails.sh to dist Thu Jan 17 11:42:35 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * nua_stack.c: removed noisy debug message from nua_client_request_sendmsg() Fri Jan 18 11:06:10 EST 2008 Pekka.Pessi@nokia.com * nua: Added NUA_ERROR_AT() macro Made internally generated 900 (and 904) response phrases unique as suggested by Jerry Richards. Mon Jan 21 10:39:50 EST 2008 Stefan Knoblich * TLS debug cleanup Mon Jan 21 12:05:38 EST 2008 Pekka.Pessi@nokia.com * tport: build fixes from Freeswitch Mon Jan 21 12:14:25 EST 2008 Pekka.Pessi@nokia.com * su_global_log.c: disable warning on SU_DEBUG[] (Doxygen-only variable) Patch from Michael Jerris. Mon Jan 21 12:15:19 EST 2008 Pekka.Pessi@nokia.com * sres.c: default log level to the same as SU_DEBUG define Patch by Michael Jerris Mon Jan 21 12:16:39 EST 2008 Pekka.Pessi@nokia.com * stun.c: default log level to the same as SU_DEBUG define Patch by Michael Jerris Mon Jan 21 12:45:04 EST 2008 Stefan Knoblich * TLS debug cleanup, 2/2. Silence openssl messages, part 2 of 2. Changed to TPORT_DEBUG=1 (thanks MikeJ). This one converts all ERR_print_errors() calls Mon Jan 21 13:00:49 EST 2008 Pekka.Pessi@nokia.com * nua: removed asserts() on hairy dialog/request handling cases Mon Jan 21 14:06:35 EST 2008 Pekka.Pessi@nokia.com * soa.c: using session state in soa_set_activity() The media mode bits are set using (local) session description instead of remote offer/answer when O/A has been completed. Mon Jan 21 14:08:08 EST 2008 Pekka.Pessi@nokia.com * soa_static.c: soa_sdp_mode_set() now includes wanted media state in offer The wanted media state is based on original user SDP and SOATAG_HOLD() content. Removed soa_sdp_mode_set_is_needed(), using dry-run parameter instead. Mon Jan 21 14:09:11 EST 2008 Pekka.Pessi@nokia.com * nua_subnotref.c: fixed REFER re-try case REFER trashed its dialog when it got retried if there was no other dialog usages. Mon Jan 21 14:20:31 EST 2008 Pekka.Pessi@nokia.com * nua_stack.c: return specific error phrases from nua_client_init_request() As suggested by Jerry Richards. Tue Jan 22 11:15:04 EST 2008 Pekka.Pessi@nokia.com * sip_util.c: updated sip_response_terminates_dialog() as per RFC 5057. Changes handling of 423 in case of SUBSCRIBE. Tue Jan 22 11:34:01 EST 2008 Pekka.Pessi@nokia.com * conformance.docs: added RFC 5057 (sipping-dialogusage) Tue Jan 22 11:34:16 EST 2008 Pekka.Pessi@nokia.com * test_auth_digest.c: testing empty realm Tue Jan 22 11:35:44 EST 2008 Pekka.Pessi@nokia.com * test_soa.c: testing hold with inactive, offered mode and setting remote activity flags while in hold Tue Jan 22 12:27:41 EST 2008 Pekka.Pessi@nokia.com * nta.c: fixed memory corruption in case sending ACK failed Thanks for Fabio Margarido for reporting this problem. Tue Jan 22 12:49:02 EST 2008 Pekka.Pessi@nokia.com * nua/test_refer.c: run test_challenge_refer() only if we use proxy Test case is now more deterministic, too. Tue Jan 22 12:51:59 EST 2008 Pekka.Pessi@nokia.com * docs/Makefile.am, docs/conformance.docs: fixed links to RFC 5057. Tue Jan 22 13:57:38 EST 2008 Pekka.Pessi@nokia.com * sres: added ttl parameter to sres_set_cached_srv_priority() and sres_cache_set_srv_priority(). Tue Jan 22 13:59:44 EST 2008 Pekka.Pessi@nokia.com * nta.c: added NTATAG_GRAYLIST(). Use NTATAG_GRAYLIST() as ttl value for sres_set_cached_srv_priority(). Tue Jan 22 14:04:29 EST 2008 Pekka.Pessi@nokia.com * RELEASE: updated. Tue Jan 22 14:04:29 EST 2008 Pekka.Pessi@nokia.com * RELEASE: updated. Wed Jan 23 06:56:11 EST 2008 Pekka.Pessi@nokia.com * sip_extra.c, sip_parser.c: updated documentation Wed Jan 23 09:47:50 EST 2008 Pekka.Pessi@nokia.com * test_nta.c: fixed receiving with sink socket Wed Jan 23 10:07:30 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * soa_static.c: fixed signedness error Wed Jan 23 10:11:14 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * win32 project files: fixed slash direction Wed Jan 23 10:13:00 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * torture_su.c: set blocking on Wed Jan 23 10:13:36 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * test_tport.c: using blocking sockets in test_incomplete() Wed Jan 23 11:01:11 EST 2008 Pekka.Pessi@nokia.com * nta.c: now using RFC3261-compliant dialog-matching Wed Jan 23 11:05:23 EST 2008 Pekka.Pessi@nokia.com * nta.c: ignore tags in nta_leg_by_dialog() if they are empty strings Wed Jan 23 11:05:58 EST 2008 Pekka.Pessi@nokia.com * nta.c: asserting in proper place when handling queue tail Wed Jan 23 12:11:09 EST 2008 Pekka.Pessi@nokia.com * torture_sip.c: added tests for accessing other extra headers beside P-Asserted-Identity/P-Preferred-Identity Wed Jan 23 13:08:55 EST 2008 Pekka.Pessi@nokia.com * nua: terminate dialog when redirected and re-establish it with new request Wed Jan 23 13:18:16 EST 2008 Pekka.Pessi@nokia.com * test_100rel.c: added test for redirect after 100rel response. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7328 d0543943-73ff-0310-b7d9-9358b9ac24b2
2008-01-23 18:37:33 +00:00
/** Release exclusive lock on home and decrease refcount (if home is threadsafe).
*
* @sa su_home_unlock().
*/
int su_home_mutex_unlock(su_home_t *home)
{
if (home == NULL)
return su_seterrno(EFAULT);
if (home->suh_lock) {
int error = _su_home_mutex_unlocker(home->suh_lock);
if (error)
return su_seterrno(error);
}
if (home->suh_blocks == NULL)
return su_seterrno(EINVAL), -1; /* Uninitialized home */
su_home_unref(home);
return 0;
}
/** Obtain exclusive lock on home without increasing refcount.
merge to sofia sip darcs tree. Includes multiple fixes and several merges of changes from the freeswitch tree back to darcs as follows: Mon Nov 19 22:05:07 EST 2007 Pekka Pessi <first.lastname@nokia.com> * test_htable2.c: define struct before using it in prototypes Fri Jan 11 09:12:01 EST 2008 Bernhard Suttner <suttner at comdasys.com> * Using # in SOATAG_HOLD to set media as inactive instead of sendonly Fri Jan 11 09:15:18 EST 2008 Pekka.Pessi@nokia.com * soa_tag.c: documented SOATAG_HOLD() inactive mode Fri Jan 11 09:28:46 EST 2008 Pekka.Pessi@nokia.com * su_addrinfo.c: if su_getaddrinfo() service is NULL, try both with "0" and NULL Fri Jan 11 09:30:23 EST 2008 Pekka.Pessi@nokia.com * Makefile.am: added tests to DIST_SUBDIRS Fri Jan 11 12:11:12 EST 2008 Pekka.Pessi@nokia.com * nta.c: NetModule hack re-prioritizing SRV records Original hack by Stefan Leuenberger <Stefan.Leuenberger@netmodule.com>. The hack reprioritizes the SRV records used with transaction in case a server refuses connection or it does not answer. Fri Jan 11 12:12:23 EST 2008 Pekka.Pessi@nokia.com * sres.c, sres_cache.c: NetModule hack for re-prioritizing SRV records Original hack by Stefan Leuenberger <Stefan.Leuenberger@netmodule.com>. The hack reprioritizes the SRV records used with transaction in case a server refuses connection or it does not answer. New functions sres_cache_set_srv_priority() and sres_set_cached_srv_priority(). Fri Jan 11 12:15:19 EST 2008 Pekka.Pessi@nokia.com * Makefile.am: fixed dist target Fri Jan 11 12:19:33 EST 2008 Pekka.Pessi@nokia.com * tport_internal.h: grammar in doc Mon Jan 14 06:59:17 EST 2008 Pekka.Pessi@nokia.com * su.h: IPv6 fix for Vista SDK Patch by Michael Jerris Wed Jan 16 13:20:47 EST 2008 Pekka.Pessi@nokia.com * nua: fix sf.net bug #1867753 (avoid duplicating initial route set) Thu Jan 17 07:48:10 EST 2008 Pekka.Pessi@nokia.com * sres.c, sres_cache.c: documented sres_set_cached_srv_priority(), sres_cache_set_srv_priority() Thu Jan 17 07:51:32 EST 2008 Pekka.Pessi@nokia.com * sofia-sip/su_wait.h, su_port.h, su_root.c: documented new functions and types for 1.12.8 Thu Jan 17 07:52:03 EST 2008 Pekka.Pessi@nokia.com * sofia-sip/htable2.h: marked new features for release 1.12.8 Thu Jan 17 07:52:33 EST 2008 Pekka.Pessi@nokia.com * su_alloc.c: marked new features for release 1.12.8. Thu Jan 17 07:53:01 EST 2008 Pekka.Pessi@nokia.com * AUTHORS: updated Thu Jan 17 07:53:21 EST 2008 Pekka.Pessi@nokia.com * RELEASE: added new features and bug fixes since 1.12.7 Thu Jan 17 07:55:18 EST 2008 Pekka.Pessi@nokia.com * libsofia-sip-ua/docs/Doxyfile.aliases: added @NEW_1_12_8 and @VERSION_1_12_8 Thu Jan 17 09:48:48 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * autogen.sh: use automake 1.9 unless otherwise specified Thu Jan 17 11:40:46 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * soa_static.c: cleaned inactive hold, added tests Thu Jan 17 11:41:54 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * Makefile.am: added hide_emails.sh to dist Thu Jan 17 11:42:35 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * nua_stack.c: removed noisy debug message from nua_client_request_sendmsg() Fri Jan 18 11:06:10 EST 2008 Pekka.Pessi@nokia.com * nua: Added NUA_ERROR_AT() macro Made internally generated 900 (and 904) response phrases unique as suggested by Jerry Richards. Mon Jan 21 10:39:50 EST 2008 Stefan Knoblich * TLS debug cleanup Mon Jan 21 12:05:38 EST 2008 Pekka.Pessi@nokia.com * tport: build fixes from Freeswitch Mon Jan 21 12:14:25 EST 2008 Pekka.Pessi@nokia.com * su_global_log.c: disable warning on SU_DEBUG[] (Doxygen-only variable) Patch from Michael Jerris. Mon Jan 21 12:15:19 EST 2008 Pekka.Pessi@nokia.com * sres.c: default log level to the same as SU_DEBUG define Patch by Michael Jerris Mon Jan 21 12:16:39 EST 2008 Pekka.Pessi@nokia.com * stun.c: default log level to the same as SU_DEBUG define Patch by Michael Jerris Mon Jan 21 12:45:04 EST 2008 Stefan Knoblich * TLS debug cleanup, 2/2. Silence openssl messages, part 2 of 2. Changed to TPORT_DEBUG=1 (thanks MikeJ). This one converts all ERR_print_errors() calls Mon Jan 21 13:00:49 EST 2008 Pekka.Pessi@nokia.com * nua: removed asserts() on hairy dialog/request handling cases Mon Jan 21 14:06:35 EST 2008 Pekka.Pessi@nokia.com * soa.c: using session state in soa_set_activity() The media mode bits are set using (local) session description instead of remote offer/answer when O/A has been completed. Mon Jan 21 14:08:08 EST 2008 Pekka.Pessi@nokia.com * soa_static.c: soa_sdp_mode_set() now includes wanted media state in offer The wanted media state is based on original user SDP and SOATAG_HOLD() content. Removed soa_sdp_mode_set_is_needed(), using dry-run parameter instead. Mon Jan 21 14:09:11 EST 2008 Pekka.Pessi@nokia.com * nua_subnotref.c: fixed REFER re-try case REFER trashed its dialog when it got retried if there was no other dialog usages. Mon Jan 21 14:20:31 EST 2008 Pekka.Pessi@nokia.com * nua_stack.c: return specific error phrases from nua_client_init_request() As suggested by Jerry Richards. Tue Jan 22 11:15:04 EST 2008 Pekka.Pessi@nokia.com * sip_util.c: updated sip_response_terminates_dialog() as per RFC 5057. Changes handling of 423 in case of SUBSCRIBE. Tue Jan 22 11:34:01 EST 2008 Pekka.Pessi@nokia.com * conformance.docs: added RFC 5057 (sipping-dialogusage) Tue Jan 22 11:34:16 EST 2008 Pekka.Pessi@nokia.com * test_auth_digest.c: testing empty realm Tue Jan 22 11:35:44 EST 2008 Pekka.Pessi@nokia.com * test_soa.c: testing hold with inactive, offered mode and setting remote activity flags while in hold Tue Jan 22 12:27:41 EST 2008 Pekka.Pessi@nokia.com * nta.c: fixed memory corruption in case sending ACK failed Thanks for Fabio Margarido for reporting this problem. Tue Jan 22 12:49:02 EST 2008 Pekka.Pessi@nokia.com * nua/test_refer.c: run test_challenge_refer() only if we use proxy Test case is now more deterministic, too. Tue Jan 22 12:51:59 EST 2008 Pekka.Pessi@nokia.com * docs/Makefile.am, docs/conformance.docs: fixed links to RFC 5057. Tue Jan 22 13:57:38 EST 2008 Pekka.Pessi@nokia.com * sres: added ttl parameter to sres_set_cached_srv_priority() and sres_cache_set_srv_priority(). Tue Jan 22 13:59:44 EST 2008 Pekka.Pessi@nokia.com * nta.c: added NTATAG_GRAYLIST(). Use NTATAG_GRAYLIST() as ttl value for sres_set_cached_srv_priority(). Tue Jan 22 14:04:29 EST 2008 Pekka.Pessi@nokia.com * RELEASE: updated. Tue Jan 22 14:04:29 EST 2008 Pekka.Pessi@nokia.com * RELEASE: updated. Wed Jan 23 06:56:11 EST 2008 Pekka.Pessi@nokia.com * sip_extra.c, sip_parser.c: updated documentation Wed Jan 23 09:47:50 EST 2008 Pekka.Pessi@nokia.com * test_nta.c: fixed receiving with sink socket Wed Jan 23 10:07:30 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * soa_static.c: fixed signedness error Wed Jan 23 10:11:14 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * win32 project files: fixed slash direction Wed Jan 23 10:13:00 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * torture_su.c: set blocking on Wed Jan 23 10:13:36 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * test_tport.c: using blocking sockets in test_incomplete() Wed Jan 23 11:01:11 EST 2008 Pekka.Pessi@nokia.com * nta.c: now using RFC3261-compliant dialog-matching Wed Jan 23 11:05:23 EST 2008 Pekka.Pessi@nokia.com * nta.c: ignore tags in nta_leg_by_dialog() if they are empty strings Wed Jan 23 11:05:58 EST 2008 Pekka.Pessi@nokia.com * nta.c: asserting in proper place when handling queue tail Wed Jan 23 12:11:09 EST 2008 Pekka.Pessi@nokia.com * torture_sip.c: added tests for accessing other extra headers beside P-Asserted-Identity/P-Preferred-Identity Wed Jan 23 13:08:55 EST 2008 Pekka.Pessi@nokia.com * nua: terminate dialog when redirected and re-establish it with new request Wed Jan 23 13:18:16 EST 2008 Pekka.Pessi@nokia.com * test_100rel.c: added test for redirect after 100rel response. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7328 d0543943-73ff-0310-b7d9-9358b9ac24b2
2008-01-23 18:37:33 +00:00
*
* Unless su_home_threadsafe() has been used to intialize locking on home
* object the function just returns -1.
*
* @return 0 if successful, -1 if not threadsafe, error code otherwise.
*
merge to sofia sip darcs tree. Includes multiple fixes and several merges of changes from the freeswitch tree back to darcs as follows: Mon Nov 19 22:05:07 EST 2007 Pekka Pessi <first.lastname@nokia.com> * test_htable2.c: define struct before using it in prototypes Fri Jan 11 09:12:01 EST 2008 Bernhard Suttner <suttner at comdasys.com> * Using # in SOATAG_HOLD to set media as inactive instead of sendonly Fri Jan 11 09:15:18 EST 2008 Pekka.Pessi@nokia.com * soa_tag.c: documented SOATAG_HOLD() inactive mode Fri Jan 11 09:28:46 EST 2008 Pekka.Pessi@nokia.com * su_addrinfo.c: if su_getaddrinfo() service is NULL, try both with "0" and NULL Fri Jan 11 09:30:23 EST 2008 Pekka.Pessi@nokia.com * Makefile.am: added tests to DIST_SUBDIRS Fri Jan 11 12:11:12 EST 2008 Pekka.Pessi@nokia.com * nta.c: NetModule hack re-prioritizing SRV records Original hack by Stefan Leuenberger <Stefan.Leuenberger@netmodule.com>. The hack reprioritizes the SRV records used with transaction in case a server refuses connection or it does not answer. Fri Jan 11 12:12:23 EST 2008 Pekka.Pessi@nokia.com * sres.c, sres_cache.c: NetModule hack for re-prioritizing SRV records Original hack by Stefan Leuenberger <Stefan.Leuenberger@netmodule.com>. The hack reprioritizes the SRV records used with transaction in case a server refuses connection or it does not answer. New functions sres_cache_set_srv_priority() and sres_set_cached_srv_priority(). Fri Jan 11 12:15:19 EST 2008 Pekka.Pessi@nokia.com * Makefile.am: fixed dist target Fri Jan 11 12:19:33 EST 2008 Pekka.Pessi@nokia.com * tport_internal.h: grammar in doc Mon Jan 14 06:59:17 EST 2008 Pekka.Pessi@nokia.com * su.h: IPv6 fix for Vista SDK Patch by Michael Jerris Wed Jan 16 13:20:47 EST 2008 Pekka.Pessi@nokia.com * nua: fix sf.net bug #1867753 (avoid duplicating initial route set) Thu Jan 17 07:48:10 EST 2008 Pekka.Pessi@nokia.com * sres.c, sres_cache.c: documented sres_set_cached_srv_priority(), sres_cache_set_srv_priority() Thu Jan 17 07:51:32 EST 2008 Pekka.Pessi@nokia.com * sofia-sip/su_wait.h, su_port.h, su_root.c: documented new functions and types for 1.12.8 Thu Jan 17 07:52:03 EST 2008 Pekka.Pessi@nokia.com * sofia-sip/htable2.h: marked new features for release 1.12.8 Thu Jan 17 07:52:33 EST 2008 Pekka.Pessi@nokia.com * su_alloc.c: marked new features for release 1.12.8. Thu Jan 17 07:53:01 EST 2008 Pekka.Pessi@nokia.com * AUTHORS: updated Thu Jan 17 07:53:21 EST 2008 Pekka.Pessi@nokia.com * RELEASE: added new features and bug fixes since 1.12.7 Thu Jan 17 07:55:18 EST 2008 Pekka.Pessi@nokia.com * libsofia-sip-ua/docs/Doxyfile.aliases: added @NEW_1_12_8 and @VERSION_1_12_8 Thu Jan 17 09:48:48 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * autogen.sh: use automake 1.9 unless otherwise specified Thu Jan 17 11:40:46 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * soa_static.c: cleaned inactive hold, added tests Thu Jan 17 11:41:54 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * Makefile.am: added hide_emails.sh to dist Thu Jan 17 11:42:35 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * nua_stack.c: removed noisy debug message from nua_client_request_sendmsg() Fri Jan 18 11:06:10 EST 2008 Pekka.Pessi@nokia.com * nua: Added NUA_ERROR_AT() macro Made internally generated 900 (and 904) response phrases unique as suggested by Jerry Richards. Mon Jan 21 10:39:50 EST 2008 Stefan Knoblich * TLS debug cleanup Mon Jan 21 12:05:38 EST 2008 Pekka.Pessi@nokia.com * tport: build fixes from Freeswitch Mon Jan 21 12:14:25 EST 2008 Pekka.Pessi@nokia.com * su_global_log.c: disable warning on SU_DEBUG[] (Doxygen-only variable) Patch from Michael Jerris. Mon Jan 21 12:15:19 EST 2008 Pekka.Pessi@nokia.com * sres.c: default log level to the same as SU_DEBUG define Patch by Michael Jerris Mon Jan 21 12:16:39 EST 2008 Pekka.Pessi@nokia.com * stun.c: default log level to the same as SU_DEBUG define Patch by Michael Jerris Mon Jan 21 12:45:04 EST 2008 Stefan Knoblich * TLS debug cleanup, 2/2. Silence openssl messages, part 2 of 2. Changed to TPORT_DEBUG=1 (thanks MikeJ). This one converts all ERR_print_errors() calls Mon Jan 21 13:00:49 EST 2008 Pekka.Pessi@nokia.com * nua: removed asserts() on hairy dialog/request handling cases Mon Jan 21 14:06:35 EST 2008 Pekka.Pessi@nokia.com * soa.c: using session state in soa_set_activity() The media mode bits are set using (local) session description instead of remote offer/answer when O/A has been completed. Mon Jan 21 14:08:08 EST 2008 Pekka.Pessi@nokia.com * soa_static.c: soa_sdp_mode_set() now includes wanted media state in offer The wanted media state is based on original user SDP and SOATAG_HOLD() content. Removed soa_sdp_mode_set_is_needed(), using dry-run parameter instead. Mon Jan 21 14:09:11 EST 2008 Pekka.Pessi@nokia.com * nua_subnotref.c: fixed REFER re-try case REFER trashed its dialog when it got retried if there was no other dialog usages. Mon Jan 21 14:20:31 EST 2008 Pekka.Pessi@nokia.com * nua_stack.c: return specific error phrases from nua_client_init_request() As suggested by Jerry Richards. Tue Jan 22 11:15:04 EST 2008 Pekka.Pessi@nokia.com * sip_util.c: updated sip_response_terminates_dialog() as per RFC 5057. Changes handling of 423 in case of SUBSCRIBE. Tue Jan 22 11:34:01 EST 2008 Pekka.Pessi@nokia.com * conformance.docs: added RFC 5057 (sipping-dialogusage) Tue Jan 22 11:34:16 EST 2008 Pekka.Pessi@nokia.com * test_auth_digest.c: testing empty realm Tue Jan 22 11:35:44 EST 2008 Pekka.Pessi@nokia.com * test_soa.c: testing hold with inactive, offered mode and setting remote activity flags while in hold Tue Jan 22 12:27:41 EST 2008 Pekka.Pessi@nokia.com * nta.c: fixed memory corruption in case sending ACK failed Thanks for Fabio Margarido for reporting this problem. Tue Jan 22 12:49:02 EST 2008 Pekka.Pessi@nokia.com * nua/test_refer.c: run test_challenge_refer() only if we use proxy Test case is now more deterministic, too. Tue Jan 22 12:51:59 EST 2008 Pekka.Pessi@nokia.com * docs/Makefile.am, docs/conformance.docs: fixed links to RFC 5057. Tue Jan 22 13:57:38 EST 2008 Pekka.Pessi@nokia.com * sres: added ttl parameter to sres_set_cached_srv_priority() and sres_cache_set_srv_priority(). Tue Jan 22 13:59:44 EST 2008 Pekka.Pessi@nokia.com * nta.c: added NTATAG_GRAYLIST(). Use NTATAG_GRAYLIST() as ttl value for sres_set_cached_srv_priority(). Tue Jan 22 14:04:29 EST 2008 Pekka.Pessi@nokia.com * RELEASE: updated. Tue Jan 22 14:04:29 EST 2008 Pekka.Pessi@nokia.com * RELEASE: updated. Wed Jan 23 06:56:11 EST 2008 Pekka.Pessi@nokia.com * sip_extra.c, sip_parser.c: updated documentation Wed Jan 23 09:47:50 EST 2008 Pekka.Pessi@nokia.com * test_nta.c: fixed receiving with sink socket Wed Jan 23 10:07:30 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * soa_static.c: fixed signedness error Wed Jan 23 10:11:14 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * win32 project files: fixed slash direction Wed Jan 23 10:13:00 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * torture_su.c: set blocking on Wed Jan 23 10:13:36 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * test_tport.c: using blocking sockets in test_incomplete() Wed Jan 23 11:01:11 EST 2008 Pekka.Pessi@nokia.com * nta.c: now using RFC3261-compliant dialog-matching Wed Jan 23 11:05:23 EST 2008 Pekka.Pessi@nokia.com * nta.c: ignore tags in nta_leg_by_dialog() if they are empty strings Wed Jan 23 11:05:58 EST 2008 Pekka.Pessi@nokia.com * nta.c: asserting in proper place when handling queue tail Wed Jan 23 12:11:09 EST 2008 Pekka.Pessi@nokia.com * torture_sip.c: added tests for accessing other extra headers beside P-Asserted-Identity/P-Preferred-Identity Wed Jan 23 13:08:55 EST 2008 Pekka.Pessi@nokia.com * nua: terminate dialog when redirected and re-establish it with new request Wed Jan 23 13:18:16 EST 2008 Pekka.Pessi@nokia.com * test_100rel.c: added test for redirect after 100rel response. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7328 d0543943-73ff-0310-b7d9-9358b9ac24b2
2008-01-23 18:37:33 +00:00
* @sa su_home_mutex_lock(), su_home_unlock(), su_home_trylock().
*
* @NEW_1_12_8
*/
int su_home_lock(su_home_t *home)
{
if (home == NULL)
return EFAULT;
if (home->suh_lock == NULL)
return -1; /* No-op */
return _su_home_mutex_locker(home->suh_lock);
}
/** Try to obtain exclusive lock on home without increasing refcount.
*
* @return 0 if successful, -1 if not threadsafe,
* EBUSY if already locked, error code otherwise.
*
merge to sofia sip darcs tree. Includes multiple fixes and several merges of changes from the freeswitch tree back to darcs as follows: Mon Nov 19 22:05:07 EST 2007 Pekka Pessi <first.lastname@nokia.com> * test_htable2.c: define struct before using it in prototypes Fri Jan 11 09:12:01 EST 2008 Bernhard Suttner <suttner at comdasys.com> * Using # in SOATAG_HOLD to set media as inactive instead of sendonly Fri Jan 11 09:15:18 EST 2008 Pekka.Pessi@nokia.com * soa_tag.c: documented SOATAG_HOLD() inactive mode Fri Jan 11 09:28:46 EST 2008 Pekka.Pessi@nokia.com * su_addrinfo.c: if su_getaddrinfo() service is NULL, try both with "0" and NULL Fri Jan 11 09:30:23 EST 2008 Pekka.Pessi@nokia.com * Makefile.am: added tests to DIST_SUBDIRS Fri Jan 11 12:11:12 EST 2008 Pekka.Pessi@nokia.com * nta.c: NetModule hack re-prioritizing SRV records Original hack by Stefan Leuenberger <Stefan.Leuenberger@netmodule.com>. The hack reprioritizes the SRV records used with transaction in case a server refuses connection or it does not answer. Fri Jan 11 12:12:23 EST 2008 Pekka.Pessi@nokia.com * sres.c, sres_cache.c: NetModule hack for re-prioritizing SRV records Original hack by Stefan Leuenberger <Stefan.Leuenberger@netmodule.com>. The hack reprioritizes the SRV records used with transaction in case a server refuses connection or it does not answer. New functions sres_cache_set_srv_priority() and sres_set_cached_srv_priority(). Fri Jan 11 12:15:19 EST 2008 Pekka.Pessi@nokia.com * Makefile.am: fixed dist target Fri Jan 11 12:19:33 EST 2008 Pekka.Pessi@nokia.com * tport_internal.h: grammar in doc Mon Jan 14 06:59:17 EST 2008 Pekka.Pessi@nokia.com * su.h: IPv6 fix for Vista SDK Patch by Michael Jerris Wed Jan 16 13:20:47 EST 2008 Pekka.Pessi@nokia.com * nua: fix sf.net bug #1867753 (avoid duplicating initial route set) Thu Jan 17 07:48:10 EST 2008 Pekka.Pessi@nokia.com * sres.c, sres_cache.c: documented sres_set_cached_srv_priority(), sres_cache_set_srv_priority() Thu Jan 17 07:51:32 EST 2008 Pekka.Pessi@nokia.com * sofia-sip/su_wait.h, su_port.h, su_root.c: documented new functions and types for 1.12.8 Thu Jan 17 07:52:03 EST 2008 Pekka.Pessi@nokia.com * sofia-sip/htable2.h: marked new features for release 1.12.8 Thu Jan 17 07:52:33 EST 2008 Pekka.Pessi@nokia.com * su_alloc.c: marked new features for release 1.12.8. Thu Jan 17 07:53:01 EST 2008 Pekka.Pessi@nokia.com * AUTHORS: updated Thu Jan 17 07:53:21 EST 2008 Pekka.Pessi@nokia.com * RELEASE: added new features and bug fixes since 1.12.7 Thu Jan 17 07:55:18 EST 2008 Pekka.Pessi@nokia.com * libsofia-sip-ua/docs/Doxyfile.aliases: added @NEW_1_12_8 and @VERSION_1_12_8 Thu Jan 17 09:48:48 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * autogen.sh: use automake 1.9 unless otherwise specified Thu Jan 17 11:40:46 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * soa_static.c: cleaned inactive hold, added tests Thu Jan 17 11:41:54 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * Makefile.am: added hide_emails.sh to dist Thu Jan 17 11:42:35 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * nua_stack.c: removed noisy debug message from nua_client_request_sendmsg() Fri Jan 18 11:06:10 EST 2008 Pekka.Pessi@nokia.com * nua: Added NUA_ERROR_AT() macro Made internally generated 900 (and 904) response phrases unique as suggested by Jerry Richards. Mon Jan 21 10:39:50 EST 2008 Stefan Knoblich * TLS debug cleanup Mon Jan 21 12:05:38 EST 2008 Pekka.Pessi@nokia.com * tport: build fixes from Freeswitch Mon Jan 21 12:14:25 EST 2008 Pekka.Pessi@nokia.com * su_global_log.c: disable warning on SU_DEBUG[] (Doxygen-only variable) Patch from Michael Jerris. Mon Jan 21 12:15:19 EST 2008 Pekka.Pessi@nokia.com * sres.c: default log level to the same as SU_DEBUG define Patch by Michael Jerris Mon Jan 21 12:16:39 EST 2008 Pekka.Pessi@nokia.com * stun.c: default log level to the same as SU_DEBUG define Patch by Michael Jerris Mon Jan 21 12:45:04 EST 2008 Stefan Knoblich * TLS debug cleanup, 2/2. Silence openssl messages, part 2 of 2. Changed to TPORT_DEBUG=1 (thanks MikeJ). This one converts all ERR_print_errors() calls Mon Jan 21 13:00:49 EST 2008 Pekka.Pessi@nokia.com * nua: removed asserts() on hairy dialog/request handling cases Mon Jan 21 14:06:35 EST 2008 Pekka.Pessi@nokia.com * soa.c: using session state in soa_set_activity() The media mode bits are set using (local) session description instead of remote offer/answer when O/A has been completed. Mon Jan 21 14:08:08 EST 2008 Pekka.Pessi@nokia.com * soa_static.c: soa_sdp_mode_set() now includes wanted media state in offer The wanted media state is based on original user SDP and SOATAG_HOLD() content. Removed soa_sdp_mode_set_is_needed(), using dry-run parameter instead. Mon Jan 21 14:09:11 EST 2008 Pekka.Pessi@nokia.com * nua_subnotref.c: fixed REFER re-try case REFER trashed its dialog when it got retried if there was no other dialog usages. Mon Jan 21 14:20:31 EST 2008 Pekka.Pessi@nokia.com * nua_stack.c: return specific error phrases from nua_client_init_request() As suggested by Jerry Richards. Tue Jan 22 11:15:04 EST 2008 Pekka.Pessi@nokia.com * sip_util.c: updated sip_response_terminates_dialog() as per RFC 5057. Changes handling of 423 in case of SUBSCRIBE. Tue Jan 22 11:34:01 EST 2008 Pekka.Pessi@nokia.com * conformance.docs: added RFC 5057 (sipping-dialogusage) Tue Jan 22 11:34:16 EST 2008 Pekka.Pessi@nokia.com * test_auth_digest.c: testing empty realm Tue Jan 22 11:35:44 EST 2008 Pekka.Pessi@nokia.com * test_soa.c: testing hold with inactive, offered mode and setting remote activity flags while in hold Tue Jan 22 12:27:41 EST 2008 Pekka.Pessi@nokia.com * nta.c: fixed memory corruption in case sending ACK failed Thanks for Fabio Margarido for reporting this problem. Tue Jan 22 12:49:02 EST 2008 Pekka.Pessi@nokia.com * nua/test_refer.c: run test_challenge_refer() only if we use proxy Test case is now more deterministic, too. Tue Jan 22 12:51:59 EST 2008 Pekka.Pessi@nokia.com * docs/Makefile.am, docs/conformance.docs: fixed links to RFC 5057. Tue Jan 22 13:57:38 EST 2008 Pekka.Pessi@nokia.com * sres: added ttl parameter to sres_set_cached_srv_priority() and sres_cache_set_srv_priority(). Tue Jan 22 13:59:44 EST 2008 Pekka.Pessi@nokia.com * nta.c: added NTATAG_GRAYLIST(). Use NTATAG_GRAYLIST() as ttl value for sres_set_cached_srv_priority(). Tue Jan 22 14:04:29 EST 2008 Pekka.Pessi@nokia.com * RELEASE: updated. Tue Jan 22 14:04:29 EST 2008 Pekka.Pessi@nokia.com * RELEASE: updated. Wed Jan 23 06:56:11 EST 2008 Pekka.Pessi@nokia.com * sip_extra.c, sip_parser.c: updated documentation Wed Jan 23 09:47:50 EST 2008 Pekka.Pessi@nokia.com * test_nta.c: fixed receiving with sink socket Wed Jan 23 10:07:30 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * soa_static.c: fixed signedness error Wed Jan 23 10:11:14 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * win32 project files: fixed slash direction Wed Jan 23 10:13:00 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * torture_su.c: set blocking on Wed Jan 23 10:13:36 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * test_tport.c: using blocking sockets in test_incomplete() Wed Jan 23 11:01:11 EST 2008 Pekka.Pessi@nokia.com * nta.c: now using RFC3261-compliant dialog-matching Wed Jan 23 11:05:23 EST 2008 Pekka.Pessi@nokia.com * nta.c: ignore tags in nta_leg_by_dialog() if they are empty strings Wed Jan 23 11:05:58 EST 2008 Pekka.Pessi@nokia.com * nta.c: asserting in proper place when handling queue tail Wed Jan 23 12:11:09 EST 2008 Pekka.Pessi@nokia.com * torture_sip.c: added tests for accessing other extra headers beside P-Asserted-Identity/P-Preferred-Identity Wed Jan 23 13:08:55 EST 2008 Pekka.Pessi@nokia.com * nua: terminate dialog when redirected and re-establish it with new request Wed Jan 23 13:18:16 EST 2008 Pekka.Pessi@nokia.com * test_100rel.c: added test for redirect after 100rel response. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7328 d0543943-73ff-0310-b7d9-9358b9ac24b2
2008-01-23 18:37:33 +00:00
* @sa su_home_lock(), su_home_unlock().
*
* @NEW_1_12_8
*/
int su_home_trylock(su_home_t *home)
{
if (home == NULL)
return EFAULT;
if (home->suh_lock == NULL)
return -1; /* No-op */
return _su_home_mutex_trylocker(home->suh_lock);
}
merge to sofia sip darcs tree. Includes multiple fixes and several merges of changes from the freeswitch tree back to darcs as follows: Mon Nov 19 22:05:07 EST 2007 Pekka Pessi <first.lastname@nokia.com> * test_htable2.c: define struct before using it in prototypes Fri Jan 11 09:12:01 EST 2008 Bernhard Suttner <suttner at comdasys.com> * Using # in SOATAG_HOLD to set media as inactive instead of sendonly Fri Jan 11 09:15:18 EST 2008 Pekka.Pessi@nokia.com * soa_tag.c: documented SOATAG_HOLD() inactive mode Fri Jan 11 09:28:46 EST 2008 Pekka.Pessi@nokia.com * su_addrinfo.c: if su_getaddrinfo() service is NULL, try both with "0" and NULL Fri Jan 11 09:30:23 EST 2008 Pekka.Pessi@nokia.com * Makefile.am: added tests to DIST_SUBDIRS Fri Jan 11 12:11:12 EST 2008 Pekka.Pessi@nokia.com * nta.c: NetModule hack re-prioritizing SRV records Original hack by Stefan Leuenberger <Stefan.Leuenberger@netmodule.com>. The hack reprioritizes the SRV records used with transaction in case a server refuses connection or it does not answer. Fri Jan 11 12:12:23 EST 2008 Pekka.Pessi@nokia.com * sres.c, sres_cache.c: NetModule hack for re-prioritizing SRV records Original hack by Stefan Leuenberger <Stefan.Leuenberger@netmodule.com>. The hack reprioritizes the SRV records used with transaction in case a server refuses connection or it does not answer. New functions sres_cache_set_srv_priority() and sres_set_cached_srv_priority(). Fri Jan 11 12:15:19 EST 2008 Pekka.Pessi@nokia.com * Makefile.am: fixed dist target Fri Jan 11 12:19:33 EST 2008 Pekka.Pessi@nokia.com * tport_internal.h: grammar in doc Mon Jan 14 06:59:17 EST 2008 Pekka.Pessi@nokia.com * su.h: IPv6 fix for Vista SDK Patch by Michael Jerris Wed Jan 16 13:20:47 EST 2008 Pekka.Pessi@nokia.com * nua: fix sf.net bug #1867753 (avoid duplicating initial route set) Thu Jan 17 07:48:10 EST 2008 Pekka.Pessi@nokia.com * sres.c, sres_cache.c: documented sres_set_cached_srv_priority(), sres_cache_set_srv_priority() Thu Jan 17 07:51:32 EST 2008 Pekka.Pessi@nokia.com * sofia-sip/su_wait.h, su_port.h, su_root.c: documented new functions and types for 1.12.8 Thu Jan 17 07:52:03 EST 2008 Pekka.Pessi@nokia.com * sofia-sip/htable2.h: marked new features for release 1.12.8 Thu Jan 17 07:52:33 EST 2008 Pekka.Pessi@nokia.com * su_alloc.c: marked new features for release 1.12.8. Thu Jan 17 07:53:01 EST 2008 Pekka.Pessi@nokia.com * AUTHORS: updated Thu Jan 17 07:53:21 EST 2008 Pekka.Pessi@nokia.com * RELEASE: added new features and bug fixes since 1.12.7 Thu Jan 17 07:55:18 EST 2008 Pekka.Pessi@nokia.com * libsofia-sip-ua/docs/Doxyfile.aliases: added @NEW_1_12_8 and @VERSION_1_12_8 Thu Jan 17 09:48:48 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * autogen.sh: use automake 1.9 unless otherwise specified Thu Jan 17 11:40:46 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * soa_static.c: cleaned inactive hold, added tests Thu Jan 17 11:41:54 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * Makefile.am: added hide_emails.sh to dist Thu Jan 17 11:42:35 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * nua_stack.c: removed noisy debug message from nua_client_request_sendmsg() Fri Jan 18 11:06:10 EST 2008 Pekka.Pessi@nokia.com * nua: Added NUA_ERROR_AT() macro Made internally generated 900 (and 904) response phrases unique as suggested by Jerry Richards. Mon Jan 21 10:39:50 EST 2008 Stefan Knoblich * TLS debug cleanup Mon Jan 21 12:05:38 EST 2008 Pekka.Pessi@nokia.com * tport: build fixes from Freeswitch Mon Jan 21 12:14:25 EST 2008 Pekka.Pessi@nokia.com * su_global_log.c: disable warning on SU_DEBUG[] (Doxygen-only variable) Patch from Michael Jerris. Mon Jan 21 12:15:19 EST 2008 Pekka.Pessi@nokia.com * sres.c: default log level to the same as SU_DEBUG define Patch by Michael Jerris Mon Jan 21 12:16:39 EST 2008 Pekka.Pessi@nokia.com * stun.c: default log level to the same as SU_DEBUG define Patch by Michael Jerris Mon Jan 21 12:45:04 EST 2008 Stefan Knoblich * TLS debug cleanup, 2/2. Silence openssl messages, part 2 of 2. Changed to TPORT_DEBUG=1 (thanks MikeJ). This one converts all ERR_print_errors() calls Mon Jan 21 13:00:49 EST 2008 Pekka.Pessi@nokia.com * nua: removed asserts() on hairy dialog/request handling cases Mon Jan 21 14:06:35 EST 2008 Pekka.Pessi@nokia.com * soa.c: using session state in soa_set_activity() The media mode bits are set using (local) session description instead of remote offer/answer when O/A has been completed. Mon Jan 21 14:08:08 EST 2008 Pekka.Pessi@nokia.com * soa_static.c: soa_sdp_mode_set() now includes wanted media state in offer The wanted media state is based on original user SDP and SOATAG_HOLD() content. Removed soa_sdp_mode_set_is_needed(), using dry-run parameter instead. Mon Jan 21 14:09:11 EST 2008 Pekka.Pessi@nokia.com * nua_subnotref.c: fixed REFER re-try case REFER trashed its dialog when it got retried if there was no other dialog usages. Mon Jan 21 14:20:31 EST 2008 Pekka.Pessi@nokia.com * nua_stack.c: return specific error phrases from nua_client_init_request() As suggested by Jerry Richards. Tue Jan 22 11:15:04 EST 2008 Pekka.Pessi@nokia.com * sip_util.c: updated sip_response_terminates_dialog() as per RFC 5057. Changes handling of 423 in case of SUBSCRIBE. Tue Jan 22 11:34:01 EST 2008 Pekka.Pessi@nokia.com * conformance.docs: added RFC 5057 (sipping-dialogusage) Tue Jan 22 11:34:16 EST 2008 Pekka.Pessi@nokia.com * test_auth_digest.c: testing empty realm Tue Jan 22 11:35:44 EST 2008 Pekka.Pessi@nokia.com * test_soa.c: testing hold with inactive, offered mode and setting remote activity flags while in hold Tue Jan 22 12:27:41 EST 2008 Pekka.Pessi@nokia.com * nta.c: fixed memory corruption in case sending ACK failed Thanks for Fabio Margarido for reporting this problem. Tue Jan 22 12:49:02 EST 2008 Pekka.Pessi@nokia.com * nua/test_refer.c: run test_challenge_refer() only if we use proxy Test case is now more deterministic, too. Tue Jan 22 12:51:59 EST 2008 Pekka.Pessi@nokia.com * docs/Makefile.am, docs/conformance.docs: fixed links to RFC 5057. Tue Jan 22 13:57:38 EST 2008 Pekka.Pessi@nokia.com * sres: added ttl parameter to sres_set_cached_srv_priority() and sres_cache_set_srv_priority(). Tue Jan 22 13:59:44 EST 2008 Pekka.Pessi@nokia.com * nta.c: added NTATAG_GRAYLIST(). Use NTATAG_GRAYLIST() as ttl value for sres_set_cached_srv_priority(). Tue Jan 22 14:04:29 EST 2008 Pekka.Pessi@nokia.com * RELEASE: updated. Tue Jan 22 14:04:29 EST 2008 Pekka.Pessi@nokia.com * RELEASE: updated. Wed Jan 23 06:56:11 EST 2008 Pekka.Pessi@nokia.com * sip_extra.c, sip_parser.c: updated documentation Wed Jan 23 09:47:50 EST 2008 Pekka.Pessi@nokia.com * test_nta.c: fixed receiving with sink socket Wed Jan 23 10:07:30 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * soa_static.c: fixed signedness error Wed Jan 23 10:11:14 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * win32 project files: fixed slash direction Wed Jan 23 10:13:00 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * torture_su.c: set blocking on Wed Jan 23 10:13:36 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * test_tport.c: using blocking sockets in test_incomplete() Wed Jan 23 11:01:11 EST 2008 Pekka.Pessi@nokia.com * nta.c: now using RFC3261-compliant dialog-matching Wed Jan 23 11:05:23 EST 2008 Pekka.Pessi@nokia.com * nta.c: ignore tags in nta_leg_by_dialog() if they are empty strings Wed Jan 23 11:05:58 EST 2008 Pekka.Pessi@nokia.com * nta.c: asserting in proper place when handling queue tail Wed Jan 23 12:11:09 EST 2008 Pekka.Pessi@nokia.com * torture_sip.c: added tests for accessing other extra headers beside P-Asserted-Identity/P-Preferred-Identity Wed Jan 23 13:08:55 EST 2008 Pekka.Pessi@nokia.com * nua: terminate dialog when redirected and re-establish it with new request Wed Jan 23 13:18:16 EST 2008 Pekka.Pessi@nokia.com * test_100rel.c: added test for redirect after 100rel response. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7328 d0543943-73ff-0310-b7d9-9358b9ac24b2
2008-01-23 18:37:33 +00:00
/** Release exclusive lock on home.
*
* Release lock without decreasing refcount.
*
* @return 0 if successful, -1 if not threadsafe, error code otherwise.
merge to sofia sip darcs tree. Includes multiple fixes and several merges of changes from the freeswitch tree back to darcs as follows: Mon Nov 19 22:05:07 EST 2007 Pekka Pessi <first.lastname@nokia.com> * test_htable2.c: define struct before using it in prototypes Fri Jan 11 09:12:01 EST 2008 Bernhard Suttner <suttner at comdasys.com> * Using # in SOATAG_HOLD to set media as inactive instead of sendonly Fri Jan 11 09:15:18 EST 2008 Pekka.Pessi@nokia.com * soa_tag.c: documented SOATAG_HOLD() inactive mode Fri Jan 11 09:28:46 EST 2008 Pekka.Pessi@nokia.com * su_addrinfo.c: if su_getaddrinfo() service is NULL, try both with "0" and NULL Fri Jan 11 09:30:23 EST 2008 Pekka.Pessi@nokia.com * Makefile.am: added tests to DIST_SUBDIRS Fri Jan 11 12:11:12 EST 2008 Pekka.Pessi@nokia.com * nta.c: NetModule hack re-prioritizing SRV records Original hack by Stefan Leuenberger <Stefan.Leuenberger@netmodule.com>. The hack reprioritizes the SRV records used with transaction in case a server refuses connection or it does not answer. Fri Jan 11 12:12:23 EST 2008 Pekka.Pessi@nokia.com * sres.c, sres_cache.c: NetModule hack for re-prioritizing SRV records Original hack by Stefan Leuenberger <Stefan.Leuenberger@netmodule.com>. The hack reprioritizes the SRV records used with transaction in case a server refuses connection or it does not answer. New functions sres_cache_set_srv_priority() and sres_set_cached_srv_priority(). Fri Jan 11 12:15:19 EST 2008 Pekka.Pessi@nokia.com * Makefile.am: fixed dist target Fri Jan 11 12:19:33 EST 2008 Pekka.Pessi@nokia.com * tport_internal.h: grammar in doc Mon Jan 14 06:59:17 EST 2008 Pekka.Pessi@nokia.com * su.h: IPv6 fix for Vista SDK Patch by Michael Jerris Wed Jan 16 13:20:47 EST 2008 Pekka.Pessi@nokia.com * nua: fix sf.net bug #1867753 (avoid duplicating initial route set) Thu Jan 17 07:48:10 EST 2008 Pekka.Pessi@nokia.com * sres.c, sres_cache.c: documented sres_set_cached_srv_priority(), sres_cache_set_srv_priority() Thu Jan 17 07:51:32 EST 2008 Pekka.Pessi@nokia.com * sofia-sip/su_wait.h, su_port.h, su_root.c: documented new functions and types for 1.12.8 Thu Jan 17 07:52:03 EST 2008 Pekka.Pessi@nokia.com * sofia-sip/htable2.h: marked new features for release 1.12.8 Thu Jan 17 07:52:33 EST 2008 Pekka.Pessi@nokia.com * su_alloc.c: marked new features for release 1.12.8. Thu Jan 17 07:53:01 EST 2008 Pekka.Pessi@nokia.com * AUTHORS: updated Thu Jan 17 07:53:21 EST 2008 Pekka.Pessi@nokia.com * RELEASE: added new features and bug fixes since 1.12.7 Thu Jan 17 07:55:18 EST 2008 Pekka.Pessi@nokia.com * libsofia-sip-ua/docs/Doxyfile.aliases: added @NEW_1_12_8 and @VERSION_1_12_8 Thu Jan 17 09:48:48 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * autogen.sh: use automake 1.9 unless otherwise specified Thu Jan 17 11:40:46 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * soa_static.c: cleaned inactive hold, added tests Thu Jan 17 11:41:54 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * Makefile.am: added hide_emails.sh to dist Thu Jan 17 11:42:35 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * nua_stack.c: removed noisy debug message from nua_client_request_sendmsg() Fri Jan 18 11:06:10 EST 2008 Pekka.Pessi@nokia.com * nua: Added NUA_ERROR_AT() macro Made internally generated 900 (and 904) response phrases unique as suggested by Jerry Richards. Mon Jan 21 10:39:50 EST 2008 Stefan Knoblich * TLS debug cleanup Mon Jan 21 12:05:38 EST 2008 Pekka.Pessi@nokia.com * tport: build fixes from Freeswitch Mon Jan 21 12:14:25 EST 2008 Pekka.Pessi@nokia.com * su_global_log.c: disable warning on SU_DEBUG[] (Doxygen-only variable) Patch from Michael Jerris. Mon Jan 21 12:15:19 EST 2008 Pekka.Pessi@nokia.com * sres.c: default log level to the same as SU_DEBUG define Patch by Michael Jerris Mon Jan 21 12:16:39 EST 2008 Pekka.Pessi@nokia.com * stun.c: default log level to the same as SU_DEBUG define Patch by Michael Jerris Mon Jan 21 12:45:04 EST 2008 Stefan Knoblich * TLS debug cleanup, 2/2. Silence openssl messages, part 2 of 2. Changed to TPORT_DEBUG=1 (thanks MikeJ). This one converts all ERR_print_errors() calls Mon Jan 21 13:00:49 EST 2008 Pekka.Pessi@nokia.com * nua: removed asserts() on hairy dialog/request handling cases Mon Jan 21 14:06:35 EST 2008 Pekka.Pessi@nokia.com * soa.c: using session state in soa_set_activity() The media mode bits are set using (local) session description instead of remote offer/answer when O/A has been completed. Mon Jan 21 14:08:08 EST 2008 Pekka.Pessi@nokia.com * soa_static.c: soa_sdp_mode_set() now includes wanted media state in offer The wanted media state is based on original user SDP and SOATAG_HOLD() content. Removed soa_sdp_mode_set_is_needed(), using dry-run parameter instead. Mon Jan 21 14:09:11 EST 2008 Pekka.Pessi@nokia.com * nua_subnotref.c: fixed REFER re-try case REFER trashed its dialog when it got retried if there was no other dialog usages. Mon Jan 21 14:20:31 EST 2008 Pekka.Pessi@nokia.com * nua_stack.c: return specific error phrases from nua_client_init_request() As suggested by Jerry Richards. Tue Jan 22 11:15:04 EST 2008 Pekka.Pessi@nokia.com * sip_util.c: updated sip_response_terminates_dialog() as per RFC 5057. Changes handling of 423 in case of SUBSCRIBE. Tue Jan 22 11:34:01 EST 2008 Pekka.Pessi@nokia.com * conformance.docs: added RFC 5057 (sipping-dialogusage) Tue Jan 22 11:34:16 EST 2008 Pekka.Pessi@nokia.com * test_auth_digest.c: testing empty realm Tue Jan 22 11:35:44 EST 2008 Pekka.Pessi@nokia.com * test_soa.c: testing hold with inactive, offered mode and setting remote activity flags while in hold Tue Jan 22 12:27:41 EST 2008 Pekka.Pessi@nokia.com * nta.c: fixed memory corruption in case sending ACK failed Thanks for Fabio Margarido for reporting this problem. Tue Jan 22 12:49:02 EST 2008 Pekka.Pessi@nokia.com * nua/test_refer.c: run test_challenge_refer() only if we use proxy Test case is now more deterministic, too. Tue Jan 22 12:51:59 EST 2008 Pekka.Pessi@nokia.com * docs/Makefile.am, docs/conformance.docs: fixed links to RFC 5057. Tue Jan 22 13:57:38 EST 2008 Pekka.Pessi@nokia.com * sres: added ttl parameter to sres_set_cached_srv_priority() and sres_cache_set_srv_priority(). Tue Jan 22 13:59:44 EST 2008 Pekka.Pessi@nokia.com * nta.c: added NTATAG_GRAYLIST(). Use NTATAG_GRAYLIST() as ttl value for sres_set_cached_srv_priority(). Tue Jan 22 14:04:29 EST 2008 Pekka.Pessi@nokia.com * RELEASE: updated. Tue Jan 22 14:04:29 EST 2008 Pekka.Pessi@nokia.com * RELEASE: updated. Wed Jan 23 06:56:11 EST 2008 Pekka.Pessi@nokia.com * sip_extra.c, sip_parser.c: updated documentation Wed Jan 23 09:47:50 EST 2008 Pekka.Pessi@nokia.com * test_nta.c: fixed receiving with sink socket Wed Jan 23 10:07:30 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * soa_static.c: fixed signedness error Wed Jan 23 10:11:14 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * win32 project files: fixed slash direction Wed Jan 23 10:13:00 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * torture_su.c: set blocking on Wed Jan 23 10:13:36 EST 2008 Pekka Pessi <Pekka.Pessi@nokia.com> * test_tport.c: using blocking sockets in test_incomplete() Wed Jan 23 11:01:11 EST 2008 Pekka.Pessi@nokia.com * nta.c: now using RFC3261-compliant dialog-matching Wed Jan 23 11:05:23 EST 2008 Pekka.Pessi@nokia.com * nta.c: ignore tags in nta_leg_by_dialog() if they are empty strings Wed Jan 23 11:05:58 EST 2008 Pekka.Pessi@nokia.com * nta.c: asserting in proper place when handling queue tail Wed Jan 23 12:11:09 EST 2008 Pekka.Pessi@nokia.com * torture_sip.c: added tests for accessing other extra headers beside P-Asserted-Identity/P-Preferred-Identity Wed Jan 23 13:08:55 EST 2008 Pekka.Pessi@nokia.com * nua: terminate dialog when redirected and re-establish it with new request Wed Jan 23 13:18:16 EST 2008 Pekka.Pessi@nokia.com * test_100rel.c: added test for redirect after 100rel response. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7328 d0543943-73ff-0310-b7d9-9358b9ac24b2
2008-01-23 18:37:33 +00:00
*
* @sa su_home_lock(), su_home_trylock(), su_home_mutex_unlock().
*
* @NEW_1_12_8
*/
int su_home_unlock(su_home_t *home)
{
if (home == NULL)
return EFAULT;
if (home->suh_lock == NULL)
return -1; /* No-op */
return _su_home_mutex_unlocker(home->suh_lock);
}
/** Initialize statistics structure */
void su_home_init_stats(su_home_t *home)
{
su_block_t *sub;
size_t size;
if (home == NULL)
return;
sub = home->suh_blocks;
if (!sub)
sub = home->suh_blocks = su_hash_alloc(SUB_N);
if (!sub)
return;
if (!sub->sub_stats) {
size = sizeof (*sub->sub_stats);
sub->sub_stats = malloc(size);
if (!sub->sub_stats)
return;
}
else
size = sub->sub_stats->hs_size;
memset(sub->sub_stats, 0, size);
sub->sub_stats->hs_size = (int)size;
sub->sub_stats->hs_blocksize = sub->sub_n;
}
/** Retrieve statistics from memory home.
*/
void su_home_get_stats(su_home_t *home, int include_clones,
su_home_stat_t hs[1],
isize_t size)
{
su_block_t *sub;
if (hs == NULL || size < (sizeof hs->hs_size))
return;
memset(hs, 0, size);
sub = MEMLOCK(home);
if (sub && sub->sub_stats) {
int sub_size = sub->sub_stats->hs_size;
if (sub_size > (int)size)
sub_size = (int)size;
sub->sub_stats->hs_preload.hsp_size = sub->sub_prsize;
sub->sub_stats->hs_preload.hsp_used = sub->sub_prused;
memcpy(hs, sub->sub_stats, sub_size);
hs->hs_size = sub_size;
}
UNLOCK(home);
}
static
void su_home_stats_alloc(su_block_t *sub, void *p, void *preload,
size_t size, int zero)
{
su_home_stat_t *hs = sub->sub_stats;
size_t rsize = ALIGN(size);
hs->hs_rehash += (sub->sub_n != hs->hs_blocksize);
hs->hs_blocksize = sub->sub_n;
hs->hs_clones += zero > 1;
if (preload) {
hs->hs_allocs.hsa_preload++;
return;
}
hs->hs_allocs.hsa_number++;
hs->hs_allocs.hsa_bytes += size;
hs->hs_allocs.hsa_rbytes += rsize;
if (hs->hs_allocs.hsa_rbytes > hs->hs_allocs.hsa_maxrbytes)
hs->hs_allocs.hsa_maxrbytes = hs->hs_allocs.hsa_rbytes;
hs->hs_blocks.hsb_number++;
hs->hs_blocks.hsb_bytes += size;
hs->hs_blocks.hsb_rbytes += rsize;
}
static
void su_home_stats_free(su_block_t *sub, void *p, void *preload,
unsigned size)
{
su_home_stat_t *hs = sub->sub_stats;
size_t rsize = ALIGN(size);
if (preload) {
hs->hs_frees.hsf_preload++;
return;
}
hs->hs_frees.hsf_number++;
hs->hs_frees.hsf_bytes += size;
hs->hs_frees.hsf_rbytes += rsize;
hs->hs_blocks.hsb_number--;
hs->hs_blocks.hsb_bytes -= size;
hs->hs_blocks.hsb_rbytes -= rsize;
}
void su_home_stat_add(su_home_stat_t total[1], su_home_stat_t const hs[1])
{
total->hs_clones += hs->hs_clones;
total->hs_rehash += hs->hs_rehash;
if (total->hs_blocksize < hs->hs_blocksize)
total->hs_blocksize = hs->hs_blocksize;
total->hs_allocs.hsa_number += hs->hs_allocs.hsa_number;
total->hs_allocs.hsa_bytes += hs->hs_allocs.hsa_bytes;
total->hs_allocs.hsa_rbytes += hs->hs_allocs.hsa_rbytes;
total->hs_allocs.hsa_maxrbytes += hs->hs_allocs.hsa_maxrbytes;
total->hs_frees.hsf_number += hs->hs_frees.hsf_number;
total->hs_frees.hsf_bytes += hs->hs_frees.hsf_bytes;
total->hs_frees.hsf_rbytes += hs->hs_frees.hsf_rbytes;
total->hs_blocks.hsb_number += hs->hs_blocks.hsb_number;
total->hs_blocks.hsb_bytes += hs->hs_blocks.hsb_bytes;
total->hs_blocks.hsb_rbytes += hs->hs_blocks.hsb_rbytes;
}