summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-03-31 04:01:00 +0000
committerHavoc Pennington <hp@redhat.com>2003-03-31 04:01:00 +0000
commitbc86794f23fa538a405813fb61b531c2eacc9ae1 (patch)
tree42f040afce0d63d312d6f43bf5f6f9bb014c586a /dbus
parentd361874ef6a94a61fa3e0534d8352392edf9bbb9 (diff)
2003-03-30 Havoc Pennington <hp@pobox.com>
* bus/config-parser.c: hacking * dbus/dbus-memory.c: don't use DBusList for the list of stuff to shut down, since it could cause weirdness with the DBusList lock * dbus/dbus-list.c (_dbus_list_test): add tests for the link-oriented stack routines (alloc_link): free the mempool if the first alloc from it fails * dbus/dbus-mempool.c (struct DBusMemBlock): fix alignment issue * dbus/dbus-string.c (UNICODE_VALID): sync new version of this from GLib (_dbus_string_skip_white): new * doc/config-file.txt (Elements): add <includedir>
Diffstat (limited to 'dbus')
-rw-r--r--dbus/dbus-internals.c2
-rw-r--r--dbus/dbus-internals.h3
-rw-r--r--dbus/dbus-list.c96
-rw-r--r--dbus/dbus-list.h3
-rw-r--r--dbus/dbus-memory.c43
-rw-r--r--dbus/dbus-mempool.c9
-rw-r--r--dbus/dbus-string.c112
-rw-r--r--dbus/dbus-string.h10
-rw-r--r--dbus/dbus-threads.c3
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 (&registered_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 (&registered_globals, link);
+ dbus_free (c);
}
- _dbus_list_clear (&registered_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 (&registered_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
};