#define CONNECTION_LOCK(connection) do { \
if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); } \
- _dbus_mutex_lock ((connection)->mutex); \
+ _dbus_rmutex_lock ((connection)->mutex); \
TOOK_LOCK_CHECK (connection); \
} while (0)
#define CONNECTION_UNLOCK(connection) _dbus_connection_unlock (connection)
#define SLOTS_LOCK(connection) do { \
- _dbus_mutex_lock ((connection)->slot_mutex); \
+ _dbus_rmutex_lock ((connection)->slot_mutex); \
} while (0)
#define SLOTS_UNLOCK(connection) do { \
- _dbus_mutex_unlock ((connection)->slot_mutex); \
+ _dbus_rmutex_unlock ((connection)->slot_mutex); \
} while (0)
#define DISPATCH_STATUS_NAME(s) \
{
DBusAtomic refcount; /**< Reference count. */
- DBusMutex *mutex; /**< Lock on the entire DBusConnection */
+ DBusRMutex *mutex; /**< Lock on the entire DBusConnection */
- DBusMutex *dispatch_mutex; /**< Protects dispatch_acquired */
+ DBusCMutex *dispatch_mutex; /**< Protects dispatch_acquired */
DBusCondVar *dispatch_cond; /**< Notify when dispatch_acquired is available */
- DBusMutex *io_path_mutex; /**< Protects io_path_acquired */
+ DBusCMutex *io_path_mutex; /**< Protects io_path_acquired */
DBusCondVar *io_path_cond; /**< Notify when io_path_acquired is available */
DBusList *outgoing_messages; /**< Queue of messages we need to send, send the end of the list first. */
DBusList *filter_list; /**< List of filters. */
- DBusMutex *slot_mutex; /**< Lock on slot_list so overall connection lock need not be taken */
+ DBusRMutex *slot_mutex; /**< Lock on slot_list so overall connection lock need not be taken */
DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */
DBusHashTable *pending_replies; /**< Hash of message serials to #DBusPendingCall. */
connection->expired_messages = NULL;
RELEASING_LOCK_CHECK (connection);
- _dbus_mutex_unlock (connection->mutex);
+ _dbus_rmutex_unlock (connection->mutex);
for (iter = _dbus_list_pop_first_link (&expired_messages);
iter != NULL;
DBusCondVar **dispatch_cond_loc,
DBusCondVar **io_path_cond_loc)
{
- *mutex_loc = connection->mutex;
- *dispatch_mutex_loc = connection->dispatch_mutex;
- *io_path_mutex_loc = connection->io_path_mutex;
+ *mutex_loc = (DBusMutex *) connection->mutex;
+ *dispatch_mutex_loc = (DBusMutex *) connection->dispatch_mutex;
+ *io_path_mutex_loc = (DBusMutex *) connection->io_path_mutex;
*dispatch_cond_loc = connection->dispatch_cond;
*io_path_cond_loc = connection->io_path_cond;
}
CONNECTION_UNLOCK (connection);
_dbus_verbose ("locking io_path_mutex\n");
- _dbus_mutex_lock (connection->io_path_mutex);
+ _dbus_cmutex_lock (connection->io_path_mutex);
_dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n",
connection->io_path_acquired, timeout_milliseconds);
connection->io_path_acquired, we_acquired);
_dbus_verbose ("unlocking io_path_mutex\n");
- _dbus_mutex_unlock (connection->io_path_mutex);
+ _dbus_cmutex_unlock (connection->io_path_mutex);
CONNECTION_LOCK (connection);
HAVE_LOCK_CHECK (connection);
_dbus_verbose ("locking io_path_mutex\n");
- _dbus_mutex_lock (connection->io_path_mutex);
+ _dbus_cmutex_lock (connection->io_path_mutex);
_dbus_assert (connection->io_path_acquired);
_dbus_condvar_wake_one (connection->io_path_cond);
_dbus_verbose ("unlocking io_path_mutex\n");
- _dbus_mutex_unlock (connection->io_path_mutex);
+ _dbus_cmutex_unlock (connection->io_path_mutex);
}
/**
if (connection == NULL)
goto error;
- _dbus_mutex_new_at_location (&connection->mutex);
+ _dbus_rmutex_new_at_location (&connection->mutex);
if (connection->mutex == NULL)
goto error;
- _dbus_mutex_new_at_location (&connection->io_path_mutex);
+ _dbus_cmutex_new_at_location (&connection->io_path_mutex);
if (connection->io_path_mutex == NULL)
goto error;
- _dbus_mutex_new_at_location (&connection->dispatch_mutex);
+ _dbus_cmutex_new_at_location (&connection->dispatch_mutex);
if (connection->dispatch_mutex == NULL)
goto error;
if (connection->io_path_cond == NULL)
goto error;
- _dbus_mutex_new_at_location (&connection->slot_mutex);
+ _dbus_rmutex_new_at_location (&connection->slot_mutex);
if (connection->slot_mutex == NULL)
goto error;
{
_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_mutex_free_at_location (&connection->slot_mutex);
+ _dbus_rmutex_free_at_location (&connection->mutex);
+ _dbus_cmutex_free_at_location (&connection->io_path_mutex);
+ _dbus_cmutex_free_at_location (&connection->dispatch_mutex);
+ _dbus_rmutex_free_at_location (&connection->slot_mutex);
dbus_free (connection);
}
if (pending_replies)
_dbus_condvar_free_at_location (&connection->dispatch_cond);
_dbus_condvar_free_at_location (&connection->io_path_cond);
- _dbus_mutex_free_at_location (&connection->io_path_mutex);
- _dbus_mutex_free_at_location (&connection->dispatch_mutex);
+ _dbus_cmutex_free_at_location (&connection->io_path_mutex);
+ _dbus_cmutex_free_at_location (&connection->dispatch_mutex);
- _dbus_mutex_free_at_location (&connection->slot_mutex);
+ _dbus_rmutex_free_at_location (&connection->slot_mutex);
- _dbus_mutex_free_at_location (&connection->mutex);
+ _dbus_rmutex_free_at_location (&connection->mutex);
dbus_free (connection);
}
CONNECTION_UNLOCK (connection);
_dbus_verbose ("locking dispatch_mutex\n");
- _dbus_mutex_lock (connection->dispatch_mutex);
+ _dbus_cmutex_lock (connection->dispatch_mutex);
while (connection->dispatch_acquired)
{
connection->dispatch_acquired = TRUE;
_dbus_verbose ("unlocking dispatch_mutex\n");
- _dbus_mutex_unlock (connection->dispatch_mutex);
+ _dbus_cmutex_unlock (connection->dispatch_mutex);
CONNECTION_LOCK (connection);
_dbus_connection_unref_unlocked (connection);
HAVE_LOCK_CHECK (connection);
_dbus_verbose ("locking dispatch_mutex\n");
- _dbus_mutex_lock (connection->dispatch_mutex);
+ _dbus_cmutex_lock (connection->dispatch_mutex);
_dbus_assert (connection->dispatch_acquired);
_dbus_condvar_wake_one (connection->dispatch_cond);
_dbus_verbose ("unlocking dispatch_mutex\n");
- _dbus_mutex_unlock (connection->dispatch_mutex);
+ _dbus_cmutex_unlock (connection->dispatch_mutex);
}
static void
*/
dbus_bool_t
_dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator,
- DBusMutex **mutex_loc,
+ DBusRMutex **mutex_loc,
dbus_int32_t *slot_id_p)
{
dbus_int32_t slot;
- _dbus_mutex_lock (*mutex_loc);
+ _dbus_rmutex_lock (*mutex_loc);
if (allocator->n_allocated_slots == 0)
{
slot, allocator, allocator->n_allocated_slots, allocator->n_used_slots);
out:
- _dbus_mutex_unlock (*(allocator->lock_loc));
+ _dbus_rmutex_unlock (*(allocator->lock_loc));
return slot >= 0;
}
_dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator,
dbus_int32_t *slot_id_p)
{
- _dbus_mutex_lock (*(allocator->lock_loc));
+ _dbus_rmutex_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);
if (allocator->allocated_slots[*slot_id_p].refcount > 0)
{
- _dbus_mutex_unlock (*(allocator->lock_loc));
+ _dbus_rmutex_unlock (*(allocator->lock_loc));
return;
}
if (allocator->n_used_slots == 0)
{
- DBusMutex **mutex_loc = allocator->lock_loc;
+ DBusRMutex **mutex_loc = allocator->lock_loc;
dbus_free (allocator->allocated_slots);
allocator->allocated_slots = NULL;
allocator->n_allocated_slots = 0;
allocator->lock_loc = NULL;
- _dbus_mutex_unlock (*mutex_loc);
+ _dbus_rmutex_unlock (*mutex_loc);
}
else
{
- _dbus_mutex_unlock (*(allocator->lock_loc));
+ _dbus_rmutex_unlock (*(allocator->lock_loc));
}
}
* be e.g. realloc()ing allocated_slots. We avoid doing this if asserts
* are disabled, since then the asserts are empty.
*/
- _dbus_mutex_lock (*(allocator->lock_loc));
+ _dbus_rmutex_lock (*(allocator->lock_loc));
_dbus_assert (slot < allocator->n_allocated_slots);
_dbus_assert (allocator->allocated_slots[slot].slot_id == slot);
- _dbus_mutex_unlock (*(allocator->lock_loc));
+ _dbus_rmutex_unlock (*(allocator->lock_loc));
#endif
if (slot >= list->n_slots)
* be e.g. realloc()ing allocated_slots. We avoid doing this if asserts
* are disabled, since then the asserts are empty.
*/
- _dbus_mutex_lock (*(allocator->lock_loc));
+ _dbus_rmutex_lock (*(allocator->lock_loc));
_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_loc));
+ _dbus_rmutex_unlock (*(allocator->lock_loc));
#endif
if (slot >= list->n_slots)
int i;
DBusFreeFunction old_free_func;
void *old_data;
- DBusMutex *mutex;
+ DBusRMutex *mutex;
if (!_dbus_data_slot_allocator_init (&allocator))
_dbus_assert_not_reached ("no memory for allocator");
_dbus_data_slot_list_init (&list);
- _dbus_mutex_new_at_location (&mutex);
+ _dbus_rmutex_new_at_location (&mutex);
if (mutex == NULL)
_dbus_assert_not_reached ("failed to alloc mutex");
++i;
}
- _dbus_mutex_free_at_location (&mutex);
+ _dbus_rmutex_free_at_location (&mutex);
return TRUE;
}
DBusAllocatedSlot *allocated_slots; /**< Allocated slots */
int n_allocated_slots; /**< number of slots malloc'd */
int n_used_slots; /**< number of slots used */
- DBusMutex **lock_loc; /**< location of thread lock */
+ DBusRMutex **lock_loc; /**< location of thread lock */
};
/**
dbus_bool_t _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator);
dbus_bool_t _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator,
- DBusMutex **mutex_loc,
+ DBusRMutex **mutex_loc,
int *slot_id_p);
void _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator,
int *slot_id_p);
/* Thread initializers */
#define _DBUS_LOCK_NAME(name) _dbus_lock_##name
-#define _DBUS_DECLARE_GLOBAL_LOCK(name) extern DBusMutex *_dbus_lock_##name
-#define _DBUS_DEFINE_GLOBAL_LOCK(name) DBusMutex *_dbus_lock_##name
-#define _DBUS_LOCK(name) _dbus_mutex_lock (_dbus_lock_##name)
-#define _DBUS_UNLOCK(name) _dbus_mutex_unlock (_dbus_lock_##name)
+#define _DBUS_DECLARE_GLOBAL_LOCK(name) extern DBusRMutex *_dbus_lock_##name
+#define _DBUS_DEFINE_GLOBAL_LOCK(name) DBusRMutex *_dbus_lock_##name
+#define _DBUS_LOCK(name) _dbus_rmutex_lock (_dbus_lock_##name)
+#define _DBUS_UNLOCK(name) _dbus_rmutex_unlock (_dbus_lock_##name)
/* 1-5 */
_DBUS_DECLARE_GLOBAL_LOCK (list);
{
DBusAtomic refcount; /**< Reference count. */
const DBusServerVTable *vtable; /**< Virtual methods for this instance. */
- DBusMutex *mutex; /**< Lock on the server object */
+ DBusRMutex *mutex; /**< Lock on the server object */
DBusGUID guid; /**< Globally unique ID of server */
#define SERVER_LOCK(server) do { \
if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); } \
- _dbus_mutex_lock ((server)->mutex); \
+ _dbus_rmutex_lock ((server)->mutex); \
TOOK_LOCK_CHECK (server); \
} while (0)
#define SERVER_UNLOCK(server) do { \
if (TRACE_LOCKS) { _dbus_verbose ("UNLOCK\n"); } \
RELEASING_LOCK_CHECK (server); \
- _dbus_mutex_unlock ((server)->mutex); \
+ _dbus_rmutex_unlock ((server)->mutex); \
} while (0)
DBUS_END_DECLS
if (server->address == NULL)
goto failed;
- _dbus_mutex_new_at_location (&server->mutex);
+ _dbus_rmutex_new_at_location (&server->mutex);
if (server->mutex == NULL)
goto failed;
return TRUE;
failed:
- _dbus_mutex_free_at_location (&server->mutex);
+ _dbus_rmutex_free_at_location (&server->mutex);
server->mutex = NULL;
if (server->watches)
{
_dbus_watch_list_free (server->watches);
_dbus_timeout_list_free (server->timeouts);
- _dbus_mutex_free_at_location (&server->mutex);
+ _dbus_rmutex_free_at_location (&server->mutex);
dbus_free (server->address);
dbus_server_allocate_data_slot (dbus_int32_t *slot_p)
{
return _dbus_data_slot_allocator_alloc (&slot_allocator,
- (DBusMutex **)&_DBUS_LOCK_NAME (server_slots),
+ (DBusRMutex **)&_DBUS_LOCK_NAME (server_slots),
slot_p);
}
#include <dbus/dbus-types.h>
#include <dbus/dbus-threads.h>
+/**
+ * @addtogroup DBusThreadsInternals
+ * @{
+ */
+
+/**
+ * A mutex which is recursive if possible, else non-recursive.
+ * This is typically recursive, but that cannot be relied upon.
+ */
+typedef struct DBusRMutex DBusRMutex;
+
+/**
+ * A mutex suitable for use with condition variables.
+ * This is typically non-recursive.
+ */
+typedef struct DBusCMutex DBusCMutex;
+
+/** @} */
+
DBUS_BEGIN_DECLS
-void _dbus_mutex_lock (DBusMutex *mutex);
-void _dbus_mutex_unlock (DBusMutex *mutex);
-void _dbus_mutex_new_at_location (DBusMutex **location_p);
-void _dbus_mutex_free_at_location (DBusMutex **location_p);
+void _dbus_rmutex_lock (DBusRMutex *mutex);
+void _dbus_rmutex_unlock (DBusRMutex *mutex);
+void _dbus_rmutex_new_at_location (DBusRMutex **location_p);
+void _dbus_rmutex_free_at_location (DBusRMutex **location_p);
+
+void _dbus_cmutex_lock (DBusCMutex *mutex);
+void _dbus_cmutex_unlock (DBusCMutex *mutex);
+void _dbus_cmutex_new_at_location (DBusCMutex **location_p);
+void _dbus_cmutex_free_at_location (DBusCMutex **location_p);
DBusCondVar* _dbus_condvar_new (void);
void _dbus_condvar_free (DBusCondVar *cond);
void _dbus_condvar_wait (DBusCondVar *cond,
- DBusMutex *mutex);
+ DBusCMutex *mutex);
dbus_bool_t _dbus_condvar_wait_timeout (DBusCondVar *cond,
- DBusMutex *mutex,
+ DBusCMutex *mutex,
int timeout_milliseconds);
void _dbus_condvar_wake_one (DBusCondVar *cond);
void _dbus_condvar_wake_all (DBusCondVar *cond);
static int thread_init_generation = 0;
-static DBusList *uninitialized_mutex_list = NULL;
+static DBusList *uninitialized_rmutex_list = NULL;
+static DBusList *uninitialized_cmutex_list = NULL;
static DBusList *uninitialized_condvar_list = NULL;
/** This is used for the no-op default mutex pointer, just to be distinct from #NULL */
/** This is used for the no-op default mutex pointer, just to be distinct from #NULL */
#define _DBUS_DUMMY_CONDVAR ((DBusCondVar*)0xABCDEF2)
-static void _dbus_mutex_free (DBusMutex *mutex);
+static void _dbus_mutex_free (DBusMutex *mutex, DBusMutexFreeFunction dtor);
+static void _dbus_mutex_new_at_location (DBusMutex **location_p,
+ DBusMutexNewFunction ctor,
+ DBusMutexFreeFunction dtor,
+ DBusList **uninitialized);
+static void _dbus_mutex_free_at_location (DBusMutex **location_p,
+ DBusMutexFreeFunction dtor,
+ DBusList **uninitialized);
/**
* @defgroup DBusThreadsInternals Thread functions
* @ingroup DBusInternals
- * @brief _dbus_mutex_lock(), etc.
+ * @brief _dbus_rmutex_lock(), etc.
*
* Functions and macros related to threads and thread locks.
*
*/
static DBusMutex *
-_dbus_mutex_new (void)
+_dbus_mutex_new (DBusMutexNewFunction ctor)
{
- if (thread_functions.recursive_mutex_new)
+ if (ctor)
+ return ctor ();
+ else if (thread_functions.recursive_mutex_new)
return (* thread_functions.recursive_mutex_new) ();
else if (thread_functions.mutex_new)
return (* thread_functions.mutex_new) ();
* May return #NULL even if threads are initialized, indicating
* out-of-memory.
*
+ * If possible, the mutex returned by this function is recursive, to
+ * avoid deadlocks. However, that cannot be relied on.
+ *
+ * The extra level of indirection given by allocating a pointer
+ * to point to the mutex location 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_rmutex_new_at_location (DBusRMutex **location_p)
+{
+ _dbus_mutex_new_at_location ((DBusMutex **) location_p,
+ thread_functions.recursive_mutex_new,
+ thread_functions.recursive_mutex_free,
+ &uninitialized_rmutex_list);
+}
+
+/**
+ * Creates a new mutex using the function supplied to dbus_threads_init(),
+ * or creates a no-op mutex if threads are not initialized.
+ * May return #NULL even if threads are initialized, indicating
+ * out-of-memory.
+ *
+ * The returned mutex is suitable for use with condition variables.
+ *
* The extra level of indirection given by allocating a pointer
* to point to the mutex location allows the threading
* module to swap out dummy mutexes for real a real mutex so libraries
* @param location_p the location of the new mutex, can return #NULL on OOM
*/
void
-_dbus_mutex_new_at_location (DBusMutex **location_p)
+_dbus_cmutex_new_at_location (DBusCMutex **location_p)
+{
+ _dbus_mutex_new_at_location ((DBusMutex **) location_p,
+ thread_functions.mutex_new,
+ thread_functions.mutex_free,
+ &uninitialized_cmutex_list);
+}
+
+static void
+_dbus_mutex_new_at_location (DBusMutex **location_p,
+ DBusMutexNewFunction ctor,
+ DBusMutexFreeFunction dtor,
+ DBusList **uninitialized)
{
_dbus_assert (location_p != NULL);
- *location_p = _dbus_mutex_new();
+ *location_p = _dbus_mutex_new (ctor);
if (thread_init_generation != _dbus_current_generation && *location_p)
{
- if (!_dbus_list_append (&uninitialized_mutex_list, location_p))
+ if (!_dbus_list_append (uninitialized, location_p))
{
- _dbus_mutex_free (*location_p);
+ _dbus_mutex_free (*location_p, dtor);
*location_p = NULL;
}
}
}
static void
-_dbus_mutex_free (DBusMutex *mutex)
+_dbus_mutex_free (DBusMutex *mutex,
+ DBusMutexFreeFunction dtor)
{
if (mutex)
{
- if (mutex && thread_functions.recursive_mutex_free)
+ if (dtor)
+ dtor (mutex);
+ else if (mutex && thread_functions.recursive_mutex_free)
(* thread_functions.recursive_mutex_free) (mutex);
else if (mutex && thread_functions.mutex_free)
(* thread_functions.mutex_free) (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)
+static void
+_dbus_mutex_free_at_location (DBusMutex **location_p,
+ DBusMutexFreeFunction dtor,
+ DBusList **uninitialized)
{
if (location_p)
{
if (thread_init_generation != _dbus_current_generation)
- _dbus_list_remove (&uninitialized_mutex_list, location_p);
+ _dbus_list_remove (uninitialized, location_p);
- _dbus_mutex_free (*location_p);
+ _dbus_mutex_free (*location_p, dtor);
}
}
/**
+ * Frees a DBusRMutex and removes it from the
+ * uninitialized mutex list;
+ * does nothing if passed a #NULL pointer.
+ */
+void
+_dbus_rmutex_free_at_location (DBusRMutex **location_p)
+{
+ _dbus_mutex_free_at_location ((DBusMutex **) location_p,
+ thread_functions.recursive_mutex_free,
+ &uninitialized_rmutex_list);
+}
+
+/**
+ * Frees a DBusCMutex and removes it from the
+ * uninitialized mutex list;
+ * does nothing if passed a #NULL pointer.
+ */
+void
+_dbus_cmutex_free_at_location (DBusCMutex **location_p)
+{
+ _dbus_mutex_free_at_location ((DBusMutex **) location_p,
+ thread_functions.mutex_free,
+ &uninitialized_cmutex_list);
+}
+
+/**
* Locks a mutex. Does nothing if passed a #NULL pointer.
* Locks may be recursive if threading implementation initialized
* recursive locks.
*/
void
-_dbus_mutex_lock (DBusMutex *mutex)
+_dbus_rmutex_lock (DBusRMutex *mutex)
{
- if (mutex)
+ if (mutex)
{
if (thread_functions.recursive_mutex_lock)
- (* thread_functions.recursive_mutex_lock) (mutex);
+ (* thread_functions.recursive_mutex_lock) ((DBusMutex *) mutex);
else if (thread_functions.mutex_lock)
- (* thread_functions.mutex_lock) (mutex);
+ (* thread_functions.mutex_lock) ((DBusMutex *) mutex);
+ }
+}
+
+/**
+ * Locks a mutex. Does nothing if passed a #NULL pointer.
+ * Locks may be recursive if threading implementation initialized
+ * recursive locks.
+ */
+void
+_dbus_cmutex_lock (DBusCMutex *mutex)
+{
+ if (mutex)
+ {
+ if (thread_functions.mutex_lock)
+ (* thread_functions.mutex_lock) ((DBusMutex *) mutex);
+ else if (thread_functions.recursive_mutex_lock)
+ (* thread_functions.recursive_mutex_lock) ((DBusMutex *) mutex);
}
}
* @returns #TRUE on success
*/
void
-_dbus_mutex_unlock (DBusMutex *mutex)
+_dbus_rmutex_unlock (DBusRMutex *mutex)
{
if (mutex)
{
if (thread_functions.recursive_mutex_unlock)
- (* thread_functions.recursive_mutex_unlock) (mutex);
+ (* thread_functions.recursive_mutex_unlock) ((DBusMutex *) mutex);
else if (thread_functions.mutex_unlock)
- (* thread_functions.mutex_unlock) (mutex);
+ (* thread_functions.mutex_unlock) ((DBusMutex *) mutex);
+ }
+}
+
+/**
+ * Unlocks a mutex. Does nothing if passed a #NULL pointer.
+ *
+ * @returns #TRUE on success
+ */
+void
+_dbus_cmutex_unlock (DBusCMutex *mutex)
+{
+ if (mutex)
+ {
+ if (thread_functions.mutex_unlock)
+ (* thread_functions.mutex_unlock) ((DBusMutex *) mutex);
+ else if (thread_functions.recursive_mutex_unlock)
+ (* thread_functions.recursive_mutex_unlock) ((DBusMutex *) mutex);
}
}
*/
void
_dbus_condvar_wait (DBusCondVar *cond,
- DBusMutex *mutex)
+ DBusCMutex *mutex)
{
if (cond && mutex && thread_functions.condvar_wait)
- (* thread_functions.condvar_wait) (cond, mutex);
+ (* thread_functions.condvar_wait) (cond, (DBusMutex *) mutex);
}
/**
*/
dbus_bool_t
_dbus_condvar_wait_timeout (DBusCondVar *cond,
- DBusMutex *mutex,
+ DBusCMutex *mutex,
int timeout_milliseconds)
{
if (cond && mutex && thread_functions.condvar_wait)
- return (* thread_functions.condvar_wait_timeout) (cond, mutex, timeout_milliseconds);
+ return (* thread_functions.condvar_wait_timeout) (cond,
+ (DBusMutex *) mutex,
+ timeout_milliseconds);
else
return TRUE;
}
i = 0;
while (i < _DBUS_N_GLOBAL_LOCKS)
{
- _dbus_mutex_free (*(locks[i]));
+ _dbus_mutex_free (*(locks[i]), thread_functions.recursive_mutex_free);
*(locks[i]) = NULL;
++i;
}
static void
shutdown_uninitialized_locks (void *data)
{
- _dbus_list_clear (&uninitialized_mutex_list);
+ _dbus_list_clear (&uninitialized_rmutex_list);
+ _dbus_list_clear (&uninitialized_cmutex_list);
_dbus_list_clear (&uninitialized_condvar_list);
}
_dbus_assert (thread_init_generation != _dbus_current_generation);
- link = uninitialized_mutex_list;
+ link = uninitialized_rmutex_list;
+ while (link != NULL)
+ {
+ DBusMutex **mp;
+
+ mp = link->data;
+ _dbus_assert (*mp == _DBUS_DUMMY_MUTEX);
+
+ *mp = _dbus_mutex_new (thread_functions.recursive_mutex_new);
+ if (*mp == NULL)
+ goto fail_mutex;
+
+ link = _dbus_list_get_next_link (&uninitialized_rmutex_list, link);
+ }
+
+ link = uninitialized_cmutex_list;
while (link != NULL)
{
DBusMutex **mp;
- mp = (DBusMutex **)link->data;
+ mp = link->data;
_dbus_assert (*mp == _DBUS_DUMMY_MUTEX);
- *mp = _dbus_mutex_new ();
+ *mp = _dbus_mutex_new (thread_functions.mutex_new);
if (*mp == NULL)
goto fail_mutex;
- link = _dbus_list_get_next_link (&uninitialized_mutex_list, link);
+ link = _dbus_list_get_next_link (&uninitialized_cmutex_list, link);
}
link = uninitialized_condvar_list;
link = _dbus_list_get_next_link (&uninitialized_condvar_list, link);
}
- _dbus_list_clear (&uninitialized_mutex_list);
+ _dbus_list_clear (&uninitialized_rmutex_list);
+ _dbus_list_clear (&uninitialized_cmutex_list);
_dbus_list_clear (&uninitialized_condvar_list);
if (!_dbus_register_shutdown_func (shutdown_uninitialized_locks,
}
fail_mutex:
- link = uninitialized_mutex_list;
+ link = uninitialized_rmutex_list;
while (link != NULL)
{
DBusMutex **mp;
- mp = (DBusMutex **)link->data;
+ mp = link->data;
if (*mp != _DBUS_DUMMY_MUTEX)
- _dbus_mutex_free (*mp);
+ _dbus_mutex_free (*mp, thread_functions.recursive_mutex_free);
else
break;
*mp = _DBUS_DUMMY_MUTEX;
- link = _dbus_list_get_next_link (&uninitialized_mutex_list, link);
+ link = _dbus_list_get_next_link (&uninitialized_rmutex_list, link);
+ }
+
+ link = uninitialized_cmutex_list;
+ while (link != NULL)
+ {
+ DBusMutex **mp;
+
+ mp = link->data;
+
+ if (*mp != _DBUS_DUMMY_MUTEX)
+ _dbus_mutex_free (*mp, thread_functions.mutex_free);
+ else
+ break;
+
+ *mp = _DBUS_DUMMY_MUTEX;
+
+ link = _dbus_list_get_next_link (&uninitialized_cmutex_list, link);
}
return FALSE;
init_locks (void)
{
int i;
- DBusMutex ***dynamic_global_locks;
-
- DBusMutex **global_locks[] = {
+ DBusRMutex ***dynamic_global_locks;
+ DBusRMutex **global_locks[] = {
#define LOCK_ADDR(name) (& _dbus_lock_##name)
LOCK_ADDR (win_fds),
LOCK_ADDR (sid_atom_cache),
i = 0;
- dynamic_global_locks = dbus_new (DBusMutex**, _DBUS_N_GLOBAL_LOCKS);
+ dynamic_global_locks = dbus_new (DBusRMutex**, _DBUS_N_GLOBAL_LOCKS);
if (dynamic_global_locks == NULL)
goto failed;
while (i < _DBUS_N_ELEMENTS (global_locks))
{
- *global_locks[i] = _dbus_mutex_new ();
-
+ *global_locks[i] = (DBusRMutex *) _dbus_mutex_new (thread_functions.recursive_mutex_new);
+
if (*global_locks[i] == NULL)
goto failed;
for (i = i - 1; i >= 0; i--)
{
- _dbus_mutex_free (*global_locks[i]);
+ _dbus_mutex_free ((DBusMutex *) *global_locks[i],
+ thread_functions.recursive_mutex_free);
*global_locks[i] = NULL;
}
return FALSE;