diff options
Diffstat (limited to 'dbus')
-rw-r--r-- | dbus/dbus-internals.c | 2 | ||||
-rw-r--r-- | dbus/dbus-internals.h | 3 | ||||
-rw-r--r-- | dbus/dbus-list.c | 96 | ||||
-rw-r--r-- | dbus/dbus-list.h | 3 | ||||
-rw-r--r-- | dbus/dbus-memory.c | 43 | ||||
-rw-r--r-- | dbus/dbus-mempool.c | 9 | ||||
-rw-r--r-- | dbus/dbus-string.c | 112 | ||||
-rw-r--r-- | dbus/dbus-string.h | 10 | ||||
-rw-r--r-- | dbus/dbus-threads.c | 3 |
9 files changed, 242 insertions, 39 deletions
diff --git a/dbus/dbus-internals.c b/dbus/dbus-internals.c index 1c018b7f..6002f7ab 100644 --- a/dbus/dbus-internals.c +++ b/dbus/dbus-internals.c @@ -345,7 +345,7 @@ _dbus_test_oom_handling (const char *description, if (!(* func) (data)) return FALSE; - + approx_mallocs = _DBUS_INT_MAX - _dbus_get_fail_alloc_counter (); _dbus_verbose ("=================\n%s: about %d mallocs total\n=================\n", diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h index 9bfd0b3b..dcf01e48 100644 --- a/dbus/dbus-internals.h +++ b/dbus/dbus-internals.h @@ -212,7 +212,8 @@ _DBUS_DECLARE_GLOBAL_LOCK (atomic); _DBUS_DECLARE_GLOBAL_LOCK (message_handler); _DBUS_DECLARE_GLOBAL_LOCK (user_info); _DBUS_DECLARE_GLOBAL_LOCK (bus); -#define _DBUS_N_GLOBAL_LOCKS (7) +_DBUS_DECLARE_GLOBAL_LOCK (shutdown_funcs); +#define _DBUS_N_GLOBAL_LOCKS (8) DBUS_END_DECLS; diff --git a/dbus/dbus-list.c b/dbus/dbus-list.c index b2efff6c..c6205971 100644 --- a/dbus/dbus-list.c +++ b/dbus/dbus-list.c @@ -57,8 +57,8 @@ alloc_link (void *data) if (!_DBUS_LOCK (list)) return NULL; - - if (!list_pool) + + if (list_pool == NULL) { list_pool = _dbus_mem_pool_new (sizeof (DBusList), TRUE); @@ -67,9 +67,21 @@ alloc_link (void *data) _DBUS_UNLOCK (list); return NULL; } + + link = _dbus_mem_pool_alloc (list_pool); + if (link == NULL) + { + _dbus_mem_pool_free (list_pool); + list_pool = NULL; + _DBUS_UNLOCK (list); + return NULL; + } } - - link = _dbus_mem_pool_alloc (list_pool); + else + { + link = _dbus_mem_pool_alloc (list_pool); + } + if (link) link->data = data; @@ -80,13 +92,14 @@ alloc_link (void *data) static void free_link (DBusList *link) -{ +{ _DBUS_LOCK (list); if (_dbus_mem_pool_dealloc (list_pool, link)) { _dbus_mem_pool_free (list_pool); list_pool = NULL; } + _DBUS_UNLOCK (list); } @@ -608,6 +621,27 @@ _dbus_list_pop_last (DBusList **list) } /** + * Removes the last link in the list and returns it. This is a + * constant-time operation. + * + * @param list address of the list head. + * @returns the last link in the list, or #NULL for an empty list. + */ +DBusList* +_dbus_list_pop_last_link (DBusList **list) +{ + DBusList *link; + + link = _dbus_list_get_last_link (list); + if (link == NULL) + return NULL; + + _dbus_list_unlink (list, link); + + return link; +} + +/** * Copies a list. This is a linear-time operation. If there isn't * enough memory to copy the entire list, the destination list will be * set to #NULL. @@ -952,6 +986,58 @@ _dbus_list_test (void) _dbus_assert (list1 == NULL); _dbus_assert (list2 == NULL); + /* Test get_first_link, get_last_link, pop_first_link, pop_last_link */ + + i = 0; + while (i < 10) + { + _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); + _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); + ++i; + } + + --i; + while (i >= 0) + { + DBusList *got_link1; + DBusList *got_link2; + + DBusList *link1; + DBusList *link2; + + void *data1; + void *data2; + + got_link1 = _dbus_list_get_last_link (&list1); + got_link2 = _dbus_list_get_first_link (&list2); + + link1 = _dbus_list_pop_last_link (&list1); + link2 = _dbus_list_pop_first_link (&list2); + + _dbus_assert (got_link1 == link1); + _dbus_assert (got_link2 == link2); + + data1 = link1->data; + data2 = link2->data; + + _dbus_list_free_link (link1); + _dbus_list_free_link (link2); + + _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i); + _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i); + + verify_list (&list1); + verify_list (&list2); + + _dbus_assert (is_ascending_sequence (&list1)); + _dbus_assert (is_descending_sequence (&list2)); + + --i; + } + + _dbus_assert (list1 == NULL); + _dbus_assert (list2 == NULL); + /* Test iteration */ i = 0; diff --git a/dbus/dbus-list.h b/dbus/dbus-list.h index df068568..5f42ca3c 100644 --- a/dbus/dbus-list.h +++ b/dbus/dbus-list.h @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "gnu" -*- */ /* dbus-list.h Generic linked list utility (internal to D-BUS implementation) * - * Copyright (C) 2002 Red Hat, Inc. + * Copyright (C) 2002, 2003 Red Hat, Inc. * * Licensed under the Academic Free License version 1.2 * @@ -63,6 +63,7 @@ void* _dbus_list_get_first (DBusList **list); void* _dbus_list_pop_first (DBusList **list); void* _dbus_list_pop_last (DBusList **list); DBusList* _dbus_list_pop_first_link (DBusList **list); +DBusList* _dbus_list_pop_last_link (DBusList **list); dbus_bool_t _dbus_list_copy (DBusList **list, DBusList **dest); int _dbus_list_get_length (DBusList **list); diff --git a/dbus/dbus-memory.c b/dbus/dbus-memory.c index fbda7139..8efbec59 100644 --- a/dbus/dbus-memory.c +++ b/dbus/dbus-memory.c @@ -633,13 +633,17 @@ dbus_free_string_array (char **str_array) */ int _dbus_current_generation = 1; -static DBusList *registered_globals = NULL; +typedef struct ShutdownClosure ShutdownClosure; -typedef struct +struct ShutdownClosure { + ShutdownClosure *next; DBusShutdownFunction func; void *data; -} ShutdownClosure; +}; + +_DBUS_DEFINE_GLOBAL_LOCK (shutdown_funcs); +static ShutdownClosure *registered_globals = NULL; /** * The D-BUS library keeps some internal global variables, for example @@ -656,22 +660,18 @@ typedef struct void dbus_shutdown (void) { - DBusList *link; - - link = _dbus_list_get_first_link (®istered_globals); - while (link != NULL) + while (registered_globals != NULL) { - ShutdownClosure *c = link->data; + ShutdownClosure *c; + c = registered_globals; + registered_globals = c->next; + (* c->func) (c->data); - - dbus_free (c); - link = _dbus_list_get_next_link (®istered_globals, link); + dbus_free (c); } - _dbus_list_clear (®istered_globals); - _dbus_current_generation += 1; } @@ -693,20 +693,17 @@ _dbus_register_shutdown_func (DBusShutdownFunction func, if (c == NULL) return FALSE; - + c->func = func; c->data = data; - /* We prepend, then shutdown the list in order, so - * we shutdown last-registered stuff first which - * is right. - */ - if (!_dbus_list_prepend (®istered_globals, c)) - { - dbus_free (c); - return FALSE; - } + _DBUS_LOCK (shutdown_funcs); + + c->next = registered_globals; + registered_globals = c; + _DBUS_UNLOCK (shutdown_funcs); + return TRUE; } diff --git a/dbus/dbus-mempool.c b/dbus/dbus-mempool.c index 13ba5502..5074c7d2 100644 --- a/dbus/dbus-mempool.c +++ b/dbus/dbus-mempool.c @@ -84,7 +84,8 @@ struct DBusMemBlock * when we free the mem pool. */ - int used_so_far; /**< bytes of this block already allocated as elements. */ + /* this is a long so that "elements" is aligned */ + long used_so_far; /**< bytes of this block already allocated as elements. */ unsigned char elements[ELEMENT_PADDING]; /**< the block data, actually allocated to required size */ }; @@ -254,7 +255,7 @@ _dbus_mem_pool_alloc (DBusMemPool *pool) memset (element, '\0', pool->element_size); pool->allocated_elements += 1; - + return element; } else @@ -311,11 +312,11 @@ _dbus_mem_pool_alloc (DBusMemPool *pool) } element = &pool->blocks->elements[pool->blocks->used_so_far]; - + pool->blocks->used_so_far += pool->element_size; pool->allocated_elements += 1; - + return element; } } diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 7549dcad..0d98b379 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -633,7 +633,74 @@ _dbus_string_steal_data_len (DBusString *str, return FALSE; } - _dbus_warn ("Broken code in _dbus_string_steal_data_len(), FIXME\n"); + _dbus_warn ("Broken code in _dbus_string_steal_data_len(), see @todo, FIXME\n"); + if (!_dbus_string_steal_data (&dest, data_return)) + { + _dbus_string_free (&dest); + return FALSE; + } + + _dbus_string_free (&dest); + return TRUE; +} + + +/** + * Copies the data from the string into a char* + * + * @param str the string + * @param data_return place to return the data + * @returns #TRUE on success, #FALSE on no memory + */ +dbus_bool_t +_dbus_string_copy_data (const DBusString *str, + char **data_return) +{ + DBUS_CONST_STRING_PREAMBLE (str); + _dbus_assert (data_return != NULL); + + *data_return = dbus_malloc (real->len + 1); + if (*data_return == NULL) + return FALSE; + + memcpy (*data_return, real->str, real->len + 1); + + return TRUE; +} + +/** + * Copies a segment of the string into a char* + * + * @param str the string + * @param data_return place to return the data + * @param start start index + * @param len length to copy + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_string_copy_data_len (const DBusString *str, + char **data_return, + int start, + int len) +{ + DBusString dest; + + DBUS_CONST_STRING_PREAMBLE (str); + _dbus_assert (data_return != NULL); + _dbus_assert (start >= 0); + _dbus_assert (len >= 0); + _dbus_assert (start <= real->len); + _dbus_assert (len <= real->len - start); + + if (!_dbus_string_init (&dest, real->max_length)) + return FALSE; + + if (!_dbus_string_copy_len (str, start, len, &dest, 0)) + { + _dbus_string_free (&dest); + return FALSE; + } + if (!_dbus_string_steal_data (&dest, data_return)) { _dbus_string_free (&dest); @@ -1235,8 +1302,9 @@ _dbus_string_replace_len (const DBusString *source, */ #define UNICODE_VALID(Char) \ ((Char) < 0x110000 && \ - ((Char) < 0xD800 || (Char) >= 0xE000) && \ - (Char) != 0xFFFE && (Char) != 0xFFFF) + (((Char) & 0xFFFFF800) != 0xD800) && \ + ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \ + ((Char) & 0xFFFF) != 0xFFFF) /** * Gets a unicode character from a UTF-8 string. Does no validation; @@ -1426,6 +1494,7 @@ _dbus_string_find_blank (const DBusString *str, /** * Skips blanks from start, storing the first non-blank in *end + * (blank is space or tab). * * @param str the string * @param start where to start @@ -1459,6 +1528,43 @@ _dbus_string_skip_blank (const DBusString *str, } /** + * Skips whitespace from start, storing the first non-whitespace in *end. + * (whitespace is space, tab, newline, CR). + * + * @param str the string + * @param start where to start + * @param end where to store the first non-whitespace byte index + */ +void +_dbus_string_skip_white (const DBusString *str, + int start, + int *end) +{ + int i; + DBUS_CONST_STRING_PREAMBLE (str); + _dbus_assert (start <= real->len); + _dbus_assert (start >= 0); + + i = start; + while (i < real->len) + { + if (!(real->str[i] == ' ' || + real->str[i] == '\n' || + real->str[i] == '\r' || + real->str[i] == '\t')) + break; + + ++i; + } + + _dbus_assert (i == real->len || !(real->str[i] == ' ' || + real->str[i] == '\t')); + + if (end) + *end = i; +} + +/** * Assigns a newline-terminated or \r\n-terminated line from the front * of the string to the given dest string. The dest string's previous * contents are deleted. If the source string contains no newline, diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h index 1f7d4919..3a517e94 100644 --- a/dbus/dbus-string.h +++ b/dbus/dbus-string.h @@ -81,6 +81,12 @@ dbus_bool_t _dbus_string_steal_data_len (DBusString *str, char **data_return, int start, int len); +dbus_bool_t _dbus_string_copy_data (const DBusString *str, + char **data_return); +dbus_bool_t _dbus_string_copy_data_len (const DBusString *str, + char **data_return, + int start, + int len); int _dbus_string_get_length (const DBusString *str); @@ -175,6 +181,10 @@ void _dbus_string_skip_blank (const DBusString *str, int start, int *end); +void _dbus_string_skip_white (const DBusString *str, + int start, + int *end); + dbus_bool_t _dbus_string_equal (const DBusString *a, const DBusString *b); diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c index d481479b..15ce33ca 100644 --- a/dbus/dbus-threads.c +++ b/dbus/dbus-threads.c @@ -245,7 +245,8 @@ init_global_locks (void) LOCK_ADDR (atomic), LOCK_ADDR (message_handler), LOCK_ADDR (user_info), - LOCK_ADDR (bus) + LOCK_ADDR (bus), + LOCK_ADDR (shutdown_funcs) #undef LOCK_ADDR }; |