diff options
Diffstat (limited to 'dbus')
-rw-r--r-- | dbus/dbus-connection.c | 105 | ||||
-rw-r--r-- | dbus/dbus-dataslot.c | 42 | ||||
-rw-r--r-- | dbus/dbus-dataslot.h | 4 | ||||
-rw-r--r-- | dbus/dbus-message.c | 2 | ||||
-rw-r--r-- | dbus/dbus-pending-call.c | 2 | ||||
-rw-r--r-- | dbus/dbus-server.c | 13 | ||||
-rw-r--r-- | dbus/dbus-threads-internal.h | 31 | ||||
-rw-r--r-- | dbus/dbus-threads.c | 212 |
8 files changed, 295 insertions, 116 deletions
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 2e942064..27720998 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -347,6 +347,33 @@ _dbus_connection_queue_received_message (DBusConnection *connection, return TRUE; } + +/** + * Gets the locks so we can examine them + * + * @param connection the connection. + * @param mutex_loc return for the location of the main mutex pointer + * @param dispatch_mutex_loc return location of the dispatch mutex pointer + * @param io_path_mutex_loc return location of the io_path mutex pointer + * @param dispatch_cond_loc return location of the dispatch conditional + * variable pointer + * @param io_path_cond_loc return location of the io_path conditional + * variable pointer + */ +void +_dbus_connection_test_get_locks (DBusConnection *conn, + DBusMutex **mutex_loc, + DBusMutex **dispatch_mutex_loc, + DBusMutex **io_path_mutex_loc, + DBusCondVar **dispatch_cond_loc, + DBusCondVar **io_path_cond_loc) +{ + *mutex_loc = conn->mutex; + *dispatch_mutex_loc = conn->dispatch_mutex; + *io_path_mutex_loc = conn->io_path_mutex; + *dispatch_cond_loc = conn->dispatch_cond; + *io_path_cond_loc = conn->io_path_cond; +} #endif /** @@ -936,7 +963,8 @@ _dbus_connection_acquire_io_path (DBusConnection *connection, while (connection->io_path_acquired) { _dbus_verbose ("%s waiting for IO path to be acquirable\n", _DBUS_FUNCTION_NAME); - _dbus_condvar_wait (connection->io_path_cond, connection->io_path_mutex); + _dbus_condvar_wait (connection->io_path_cond, + connection->io_path_mutex); } } } @@ -1060,11 +1088,6 @@ _dbus_connection_new_for_transport (DBusTransport *transport) DBusWatchList *watch_list; DBusTimeoutList *timeout_list; DBusHashTable *pending_replies; - DBusMutex *mutex; - DBusMutex *io_path_mutex; - DBusMutex *dispatch_mutex; - DBusCondVar *dispatch_cond; - DBusCondVar *io_path_cond; DBusList *disconnect_link; DBusMessage *disconnect_message; DBusCounter *outgoing_counter; @@ -1074,11 +1097,6 @@ _dbus_connection_new_for_transport (DBusTransport *transport) connection = NULL; pending_replies = NULL; timeout_list = NULL; - mutex = NULL; - io_path_mutex = NULL; - dispatch_mutex = NULL; - dispatch_cond = NULL; - io_path_cond = NULL; disconnect_link = NULL; disconnect_message = NULL; outgoing_counter = NULL; @@ -1103,24 +1121,24 @@ _dbus_connection_new_for_transport (DBusTransport *transport) if (connection == NULL) goto error; - mutex = _dbus_mutex_new (); - if (mutex == NULL) + _dbus_mutex_new_at_location (&connection->mutex); + if (connection->mutex == NULL) goto error; - io_path_mutex = _dbus_mutex_new (); - if (io_path_mutex == NULL) + _dbus_mutex_new_at_location (&connection->io_path_mutex); + if (connection->io_path_mutex == NULL) goto error; - dispatch_mutex = _dbus_mutex_new (); - if (dispatch_mutex == NULL) + _dbus_mutex_new_at_location (&connection->dispatch_mutex); + if (connection->dispatch_mutex == NULL) goto error; - dispatch_cond = _dbus_condvar_new (); - if (dispatch_cond == NULL) + _dbus_condvar_new_at_location (&connection->dispatch_cond); + if (connection->dispatch_cond == NULL) goto error; - io_path_cond = _dbus_condvar_new (); - if (io_path_cond == NULL) + _dbus_condvar_new_at_location (&connection->io_path_cond); + if (connection->io_path_cond == NULL) goto error; disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL, @@ -1146,11 +1164,6 @@ _dbus_connection_new_for_transport (DBusTransport *transport) _dbus_disable_sigpipe (); connection->refcount.value = 1; - connection->mutex = mutex; - connection->dispatch_cond = dispatch_cond; - connection->dispatch_mutex = dispatch_mutex; - connection->io_path_cond = io_path_cond; - connection->io_path_mutex = io_path_mutex; connection->transport = transport; connection->watches = watch_list; connection->timeouts = timeout_list; @@ -1189,24 +1202,15 @@ _dbus_connection_new_for_transport (DBusTransport *transport) if (disconnect_link != NULL) _dbus_list_free_link (disconnect_link); - if (io_path_cond != NULL) - _dbus_condvar_free (io_path_cond); - - if (dispatch_cond != NULL) - _dbus_condvar_free (dispatch_cond); - - if (mutex != NULL) - _dbus_mutex_free (mutex); - - if (io_path_mutex != NULL) - _dbus_mutex_free (io_path_mutex); - - if (dispatch_mutex != NULL) - _dbus_mutex_free (dispatch_mutex); - if (connection != NULL) - dbus_free (connection); - + { + _dbus_condvar_free_at_location (&connection->io_path_cond); + _dbus_condvar_free_at_location (&connection->dispatch_cond); + _dbus_mutex_free_at_location (&connection->mutex); + _dbus_mutex_free_at_location (&connection->io_path_mutex); + _dbus_mutex_free_at_location (&connection->dispatch_mutex); + dbus_free (connection); + } if (pending_replies) _dbus_hash_table_unref (pending_replies); @@ -1836,13 +1840,13 @@ _dbus_connection_last_unref (DBusConnection *connection) _dbus_list_clear (&connection->link_cache); - _dbus_condvar_free (connection->dispatch_cond); - _dbus_condvar_free (connection->io_path_cond); + _dbus_condvar_free_at_location (&connection->dispatch_cond); + _dbus_condvar_free_at_location (&connection->io_path_cond); - _dbus_mutex_free (connection->io_path_mutex); - _dbus_mutex_free (connection->dispatch_mutex); + _dbus_mutex_free_at_location (&connection->io_path_mutex); + _dbus_mutex_free_at_location (&connection->dispatch_mutex); - _dbus_mutex_free (connection->mutex); + _dbus_mutex_free_at_location (&connection->mutex); dbus_free (connection); } @@ -3305,7 +3309,8 @@ _dbus_connection_acquire_dispatch (DBusConnection *connection) while (connection->dispatch_acquired) { _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME); - _dbus_condvar_wait (connection->dispatch_cond, connection->dispatch_mutex); + _dbus_condvar_wait (connection->dispatch_cond, + connection->dispatch_mutex); } _dbus_assert (!connection->dispatch_acquired); @@ -4582,7 +4587,7 @@ dbus_bool_t dbus_connection_allocate_data_slot (dbus_int32_t *slot_p) { return _dbus_data_slot_allocator_alloc (&slot_allocator, - _DBUS_LOCK_NAME (connection_slots), + &_DBUS_LOCK_NAME (connection_slots), slot_p); } diff --git a/dbus/dbus-dataslot.c b/dbus/dbus-dataslot.c index 78e94c37..d53f3bd7 100644 --- a/dbus/dbus-dataslot.c +++ b/dbus/dbus-dataslot.c @@ -46,7 +46,7 @@ _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator) allocator->allocated_slots = NULL; allocator->n_allocated_slots = 0; allocator->n_used_slots = 0; - allocator->lock = NULL; + allocator->lock_loc = NULL; return TRUE; } @@ -59,26 +59,26 @@ _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator) * is allocated and stored at *slot_id_p. * * @param allocator the allocator - * @param mutex the lock for this allocator + * @param mutex_loc the location lock for this allocator * @param slot_id_p address to fill with the slot ID * @returns #TRUE on success */ dbus_bool_t _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator, - DBusMutex *mutex, + DBusMutex **mutex_loc, dbus_int32_t *slot_id_p) { dbus_int32_t slot; - if (!_dbus_mutex_lock (mutex)) + if (!_dbus_mutex_lock (*mutex_loc)) return FALSE; if (allocator->n_allocated_slots == 0) { - _dbus_assert (allocator->lock == NULL); - allocator->lock = mutex; + _dbus_assert (allocator->lock_loc == NULL); + allocator->lock_loc = mutex_loc; } - else if (allocator->lock != mutex) + else if (allocator->lock_loc != mutex_loc) { _dbus_warn ("D-Bus threads were initialized after first using the D-Bus library. If your application does not directly initialize threads or use D-Bus, keep in mind that some library or plugin may have used D-Bus or initialized threads behind your back. You can often fix this problem by calling dbus_init_threads() or dbus_g_threads_init() early in your main() method, before D-Bus is used."); _dbus_assert_not_reached ("exiting"); @@ -145,7 +145,7 @@ _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator, slot, allocator, allocator->n_allocated_slots, allocator->n_used_slots); out: - _dbus_mutex_unlock (allocator->lock); + _dbus_mutex_unlock (*(allocator->lock_loc)); return slot >= 0; } @@ -164,7 +164,7 @@ void _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p) { - _dbus_mutex_lock (allocator->lock); + _dbus_mutex_lock (*(allocator->lock_loc)); _dbus_assert (*slot_id_p < allocator->n_allocated_slots); _dbus_assert (allocator->allocated_slots[*slot_id_p].slot_id == *slot_id_p); @@ -174,7 +174,7 @@ _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator, if (allocator->allocated_slots[*slot_id_p].refcount > 0) { - _dbus_mutex_unlock (allocator->lock); + _dbus_mutex_unlock (*(allocator->lock_loc)); return; } @@ -189,18 +189,18 @@ _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator, if (allocator->n_used_slots == 0) { - DBusMutex *mutex = allocator->lock; + DBusMutex **mutex_loc = allocator->lock_loc; dbus_free (allocator->allocated_slots); allocator->allocated_slots = NULL; allocator->n_allocated_slots = 0; - allocator->lock = NULL; + allocator->lock_loc = NULL; - _dbus_mutex_unlock (mutex); + _dbus_mutex_unlock (*mutex_loc); } else { - _dbus_mutex_unlock (allocator->lock); + _dbus_mutex_unlock (*(allocator->lock_loc)); } } @@ -246,11 +246,11 @@ _dbus_data_slot_list_set (DBusDataSlotAllocator *allocator, * be e.g. realloc()ing allocated_slots. We avoid doing this if asserts * are disabled, since then the asserts are empty. */ - if (!_dbus_mutex_lock (allocator->lock)) + if (!_dbus_mutex_lock (*(allocator->lock_loc))) return FALSE; _dbus_assert (slot < allocator->n_allocated_slots); _dbus_assert (allocator->allocated_slots[slot].slot_id == slot); - _dbus_mutex_unlock (allocator->lock); + _dbus_mutex_unlock (*(allocator->lock_loc)); #endif if (slot >= list->n_slots) @@ -304,12 +304,12 @@ _dbus_data_slot_list_get (DBusDataSlotAllocator *allocator, * be e.g. realloc()ing allocated_slots. We avoid doing this if asserts * are disabled, since then the asserts are empty. */ - if (!_dbus_mutex_lock (allocator->lock)) + if (!_dbus_mutex_lock (*(allocator->lock_loc))) return NULL; _dbus_assert (slot >= 0); _dbus_assert (slot < allocator->n_allocated_slots); _dbus_assert (allocator->allocated_slots[slot].slot_id == slot); - _dbus_mutex_unlock (allocator->lock); + _dbus_mutex_unlock (*(allocator->lock_loc)); #endif if (slot >= list->n_slots) @@ -392,7 +392,7 @@ _dbus_data_slot_test (void) _dbus_data_slot_list_init (&list); - mutex = _dbus_mutex_new (); + _dbus_mutex_new_at_location (&mutex); if (mutex == NULL) _dbus_assert_not_reached ("failed to alloc mutex"); @@ -407,7 +407,7 @@ _dbus_data_slot_test (void) */ dbus_int32_t tmp = -1; - _dbus_data_slot_allocator_alloc (&allocator, mutex, &tmp); + _dbus_data_slot_allocator_alloc (&allocator, &mutex, &tmp); if (tmp != i) _dbus_assert_not_reached ("did not allocate slots in numeric order\n"); @@ -472,7 +472,7 @@ _dbus_data_slot_test (void) ++i; } - _dbus_mutex_free (mutex); + _dbus_mutex_free_at_location (&mutex); return TRUE; } diff --git a/dbus/dbus-dataslot.h b/dbus/dbus-dataslot.h index 04c8f309..72fca619 100644 --- a/dbus/dbus-dataslot.h +++ b/dbus/dbus-dataslot.h @@ -57,7 +57,7 @@ struct DBusDataSlotAllocator DBusAllocatedSlot *allocated_slots; /**< Allocated slots */ int n_allocated_slots; /**< number of slots malloc'd */ int n_used_slots; /**< number of slots used */ - DBusMutex *lock; /**< thread lock */ + DBusMutex **lock_loc; /**< location of thread lock */ }; /** @@ -72,7 +72,7 @@ struct DBusDataSlotList dbus_bool_t _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator); dbus_bool_t _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator, - DBusMutex *mutex, + DBusMutex **mutex_loc, int *slot_id_p); void _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator, int *slot_id_p); diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index f032f82a..9b0d7a0b 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -3595,7 +3595,7 @@ dbus_bool_t dbus_message_allocate_data_slot (dbus_int32_t *slot_p) { return _dbus_data_slot_allocator_alloc (&slot_allocator, - _DBUS_LOCK_NAME (message_slots), + &_DBUS_LOCK_NAME (message_slots), slot_p); } diff --git a/dbus/dbus-pending-call.c b/dbus/dbus-pending-call.c index e6ece9dd..6076d723 100644 --- a/dbus/dbus-pending-call.c +++ b/dbus/dbus-pending-call.c @@ -651,7 +651,7 @@ dbus_bool_t dbus_pending_call_allocate_data_slot (dbus_int32_t *slot_p) { return _dbus_data_slot_allocator_alloc (&slot_allocator, - _DBUS_LOCK_NAME (pending_call_slots), + &_DBUS_LOCK_NAME (pending_call_slots), slot_p); } diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c index d1ab496a..b406c869 100644 --- a/dbus/dbus-server.c +++ b/dbus/dbus-server.c @@ -141,7 +141,7 @@ _dbus_server_init_base (DBusServer *server, if (server->address == NULL) goto failed; - server->mutex = _dbus_mutex_new (); + _dbus_mutex_new_at_location (&server->mutex); if (server->mutex == NULL) goto failed; @@ -160,11 +160,8 @@ _dbus_server_init_base (DBusServer *server, return TRUE; failed: - if (server->mutex) - { - _dbus_mutex_free (server->mutex); - server->mutex = NULL; - } + _dbus_mutex_free_at_location (&server->mutex); + server->mutex = NULL; if (server->watches) { _dbus_watch_list_free (server->watches); @@ -210,7 +207,7 @@ _dbus_server_finalize_base (DBusServer *server) _dbus_watch_list_free (server->watches); _dbus_timeout_list_free (server->timeouts); - _dbus_mutex_free (server->mutex); + _dbus_mutex_free_at_location (&server->mutex); dbus_free (server->address); @@ -1060,7 +1057,7 @@ dbus_bool_t dbus_server_allocate_data_slot (dbus_int32_t *slot_p) { return _dbus_data_slot_allocator_alloc (&slot_allocator, - _DBUS_LOCK_NAME (server_slots), + (DBusMutex **)&_DBUS_LOCK_NAME (server_slots), slot_p); } diff --git a/dbus/dbus-threads-internal.h b/dbus/dbus-threads-internal.h index 8cc3a7ac..700c4f75 100644 --- a/dbus/dbus-threads-internal.h +++ b/dbus/dbus-threads-internal.h @@ -29,21 +29,24 @@ DBUS_BEGIN_DECLS -DBusMutex* _dbus_mutex_new (void); -void _dbus_mutex_free (DBusMutex *mutex); -dbus_bool_t _dbus_mutex_lock (DBusMutex *mutex); -dbus_bool_t _dbus_mutex_unlock (DBusMutex *mutex); - -DBusCondVar* _dbus_condvar_new (void); -void _dbus_condvar_free (DBusCondVar *cond); -void _dbus_condvar_wait (DBusCondVar *cond, - DBusMutex *mutex); -dbus_bool_t _dbus_condvar_wait_timeout (DBusCondVar *cond, - DBusMutex *mutex, - int timeout_milliseconds); -void _dbus_condvar_wake_one (DBusCondVar *cond); -void _dbus_condvar_wake_all (DBusCondVar *cond); +DBusMutex* _dbus_mutex_new (void); +void _dbus_mutex_free (DBusMutex *mutex); +dbus_bool_t _dbus_mutex_lock (DBusMutex *mutex); +dbus_bool_t _dbus_mutex_unlock (DBusMutex *mutex); +void _dbus_mutex_new_at_location (DBusMutex **location_p); +void _dbus_mutex_free_at_location (DBusMutex **location_p); +DBusCondVar* _dbus_condvar_new (void); +void _dbus_condvar_free (DBusCondVar *cond); +void _dbus_condvar_wait (DBusCondVar *cond, + DBusMutex *mutex); +dbus_bool_t _dbus_condvar_wait_timeout (DBusCondVar *cond, + DBusMutex *mutex, + int timeout_milliseconds); +void _dbus_condvar_wake_one (DBusCondVar *cond); +void _dbus_condvar_wake_all (DBusCondVar *cond); +void _dbus_condvar_new_at_location (DBusCondVar **location_p); +void _dbus_condvar_free_at_location (DBusCondVar **location_p); DBUS_END_DECLS diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c index f22d0a68..78269634 100644 --- a/dbus/dbus-threads.c +++ b/dbus/dbus-threads.c @@ -23,6 +23,7 @@ #include "dbus-threads.h" #include "dbus-internals.h" #include "dbus-threads-internal.h" +#include "dbus-list.h" static DBusThreadFunctions thread_functions = { @@ -35,6 +36,9 @@ static DBusThreadFunctions thread_functions = }; static int thread_init_generation = 0; +static DBusList *uninitialized_mutex_list = NULL; +static DBusList *uninitialized_condvar_list = NULL; + /** This is used for the no-op default mutex pointer, just to be distinct from #NULL */ #define _DBUS_DUMMY_MUTEX ((DBusMutex*)0xABCDEF) @@ -69,6 +73,32 @@ _dbus_mutex_new (void) } /** + * This does the same thing as _dbus_mutex_new. It however + * gives another level of indirection by allocating a pointer + * to point to the mutex location. This allows the threading + * module to swap out dummy mutexes for real a real mutex so libraries + * can initialize threads even after the D-Bus API has been used. + * + * @param location_p the location of the new mutex, can return #NULL on OOM + */ +void +_dbus_mutex_new_at_location (DBusMutex **location_p) +{ + _dbus_assert (location_p != NULL); + + *location_p = _dbus_mutex_new(); + + if (thread_init_generation != _dbus_current_generation && *location_p) + { + if (!_dbus_list_append (&uninitialized_mutex_list, location_p)) + { + _dbus_mutex_free (*location_p); + *location_p = NULL; + } + } +} + +/** * Frees a mutex created with dbus_mutex_new(); does * nothing if passed a #NULL pointer. */ @@ -80,6 +110,23 @@ _dbus_mutex_free (DBusMutex *mutex) } /** + * Frees a mutex and removes it from the + * uninitialized_mutex_list; + * does nothing if passed a #NULL pointer. + */ +void +_dbus_mutex_free_at_location (DBusMutex **location_p) +{ + if (location_p) + { + if (thread_init_generation != _dbus_current_generation) + _dbus_list_remove (&uninitialized_mutex_list, location_p); + + _dbus_mutex_free (*location_p); + } +} + +/** * Locks a mutex. Does nothing if passed a #NULL pointer. * Locks are not recursive. * @@ -125,6 +172,33 @@ _dbus_condvar_new (void) return _DBUS_DUMMY_CONDVAR; } + +/** + * This does the same thing as _dbus_condvar_new. It however + * gives another level of indirection by allocating a pointer + * to point to the condvar location. This allows the threading + * module to swap out dummy condvars for real a real condvar so libraries + * can initialize threads even after the D-Bus API has been used. + * + * @returns the location of a new condvar or #NULL on OOM + */ + +void +_dbus_condvar_new_at_location (DBusCondVar **location_p) +{ + *location_p = _dbus_condvar_new(); + + if (thread_init_generation != _dbus_current_generation && *location_p) + { + if (!_dbus_list_append (&uninitialized_condvar_list, location_p)) + { + _dbus_condvar_free (*location_p); + *location_p = NULL; + } + } +} + + /** * Frees a conditional variable created with dbus_condvar_new(); does * nothing if passed a #NULL pointer. @@ -137,6 +211,23 @@ _dbus_condvar_free (DBusCondVar *cond) } /** + * Frees a conditional variable and removes it from the + * uninitialized_condvar_list; + * does nothing if passed a #NULL pointer. + */ +void +_dbus_condvar_free_at_location (DBusCondVar **location_p) +{ + if (location_p) + { + if (thread_init_generation != _dbus_current_generation) + _dbus_list_remove (&uninitialized_condvar_list, location_p); + + _dbus_condvar_free (*location_p); + } +} + +/** * Atomically unlocks the mutex and waits for the conditions * variable to be signalled. Locks the mutex again before * returning. @@ -214,8 +305,100 @@ shutdown_global_locks (void *data) dbus_free (locks); } +static void +shutdown_uninitialized_locks (void *data) +{ + _dbus_list_clear (&uninitialized_mutex_list); + _dbus_list_clear (&uninitialized_condvar_list); +} + static dbus_bool_t -init_global_locks (void) +init_uninitialized_locks (void) +{ + DBusList *link; + + _dbus_assert (thread_init_generation == 0); + + link = uninitialized_mutex_list; + while (link != NULL) + { + DBusMutex **mp; + + mp = (DBusMutex **)link->data; + _dbus_assert (*mp == _DBUS_DUMMY_MUTEX); + + *mp = _dbus_mutex_new (); + if (*mp == NULL) + goto fail_mutex; + + link = _dbus_list_get_next_link (&uninitialized_mutex_list, link); + } + + link = uninitialized_condvar_list; + while (link != NULL) + { + DBusCondVar **cp; + + cp = (DBusCondVar **)link->data; + _dbus_assert (*cp == _DBUS_DUMMY_CONDVAR); + + *cp = _dbus_condvar_new (); + if (*cp == NULL) + goto fail_condvar; + + link = _dbus_list_get_next_link (&uninitialized_condvar_list, link); + } + + _dbus_list_clear (&uninitialized_mutex_list); + _dbus_list_clear (&uninitialized_condvar_list); + + if (!_dbus_register_shutdown_func (shutdown_uninitialized_locks, + NULL)) + goto fail_condvar; + + return TRUE; + + fail_condvar: + link = uninitialized_condvar_list; + while (link != NULL) + { + DBusCondVar **cp; + + cp = (DBusCondVar **)link->data; + + if (*cp != _DBUS_DUMMY_CONDVAR) + _dbus_condvar_free (*cp); + else + break; + + *cp = _DBUS_DUMMY_CONDVAR; + + link = _dbus_list_get_next_link (&uninitialized_condvar_list, link); + } + + fail_mutex: + link = uninitialized_mutex_list; + while (link != NULL) + { + DBusMutex **mp; + + mp = (DBusMutex **)link->data; + + if (*mp != _DBUS_DUMMY_MUTEX) + _dbus_mutex_free (*mp); + else + break; + + *mp = _DBUS_DUMMY_MUTEX; + + link = _dbus_list_get_next_link (&uninitialized_mutex_list, link); + } + + return FALSE; +} + +static dbus_bool_t +init_locks (void) { int i; DBusMutex ***dynamic_global_locks; @@ -260,6 +443,9 @@ init_global_locks (void) if (!_dbus_register_shutdown_func (shutdown_global_locks, dynamic_global_locks)) goto failed; + + if (!init_uninitialized_locks ()) + goto failed; return TRUE; @@ -339,24 +525,12 @@ dbus_threads_init (const DBusThreadFunctions *functions) if (thread_init_generation != _dbus_current_generation) thread_functions.mask = 0; /* allow re-init in new generation */ - + + /* Silently allow multiple init + * First init wins and D-Bus will always use its threading system + */ if (thread_functions.mask != 0) - { - /* Silently allow multiple init if the functions are the same ones. - * Well, we only bother checking two of them, just out of laziness. - */ - if (thread_functions.mask == functions->mask && - thread_functions.mutex_new == functions->mutex_new && - thread_functions.condvar_new == functions->condvar_new) - { - return TRUE; - } - else - { - _dbus_warn ("dbus_threads_init() called twice with two different sets of functions\n"); - return FALSE; - } - } + return TRUE; thread_functions.mutex_new = functions->mutex_new; thread_functions.mutex_free = functions->mutex_free; @@ -372,7 +546,7 @@ dbus_threads_init (const DBusThreadFunctions *functions) thread_functions.mask = functions->mask; - if (!init_global_locks ()) + if (!init_locks ()) return FALSE; thread_init_generation = _dbus_current_generation; |