static dbus_bool_t init_global_locks (void) { int i; DBusMutex ***dynamic_global_locks; DBusMutex **global_locks[] = { #define LOCK_ADDR(name) (& _dbus_lock_##name) LOCK_ADDR (list), LOCK_ADDR (connection_slots), LOCK_ADDR (pending_call_slots), LOCK_ADDR (server_slots), LOCK_ADDR (message_slots), LOCK_ADDR (atomic), LOCK_ADDR (bus), LOCK_ADDR (shutdown_funcs), LOCK_ADDR (system_users), LOCK_ADDR (message_cache), LOCK_ADDR (shared_connections) #undef LOCK_ADDR }; _dbus_assert (_DBUS_N_ELEMENTS (global_locks) == _DBUS_N_GLOBAL_LOCKS); i = 0; dynamic_global_locks = dbus_new (DBusMutex**, _DBUS_N_GLOBAL_LOCKS); if (dynamic_global_locks == NULL) goto failed; while (i < _DBUS_N_ELEMENTS (global_locks)) { *global_locks[i] = _dbus_mutex_new (); if (*global_locks[i] == NULL) goto failed; dynamic_global_locks[i] = global_locks[i]; ++i; } if (!_dbus_register_shutdown_func (shutdown_global_locks, dynamic_global_locks)) goto failed; return TRUE; failed: dbus_free (dynamic_global_locks); for (i = i - 1; i >= 0; i--) { _dbus_mutex_free (*global_locks[i]); *global_locks[i] = NULL; } return FALSE; }
/** * 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; } } }
static dbus_bool_t init_uninitialized_locks (void) { DBusList *link; _dbus_assert (thread_init_generation != _dbus_current_generation); 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; #ifndef EMULATOR DBusMutex **global_locks[] = { #define LOCK_ADDR(name) (& _dbus_lock_##name) LOCK_ADDR (win_fds), LOCK_ADDR (sid_atom_cache), LOCK_ADDR (list), LOCK_ADDR (connection_slots), LOCK_ADDR (pending_call_slots), LOCK_ADDR (server_slots), LOCK_ADDR (message_slots), LOCK_ADDR (atomic), LOCK_ADDR (bus), LOCK_ADDR (bus_datas), LOCK_ADDR (shutdown_funcs), LOCK_ADDR (system_users), LOCK_ADDR (message_cache), LOCK_ADDR (shared_connections), LOCK_ADDR (machine_uuid) #undef LOCK_ADDR }; #else DBusMutex **global_locks[15]; #define LOCK_ADDR(name) ((DBusMutex **)& _dbus_lock_##name) global_locks[0]=LOCK_ADDR (win_fds); global_locks[1]=LOCK_ADDR (sid_atom_cache); global_locks[2]=LOCK_ADDR (list); global_locks[3]=LOCK_ADDR (connection_slots); global_locks[4]=LOCK_ADDR (pending_call_slots); global_locks[5]=LOCK_ADDR (server_slots); global_locks[6]=LOCK_ADDR (message_slots); global_locks[7]=LOCK_ADDR (atomic); global_locks[8]=LOCK_ADDR (bus); global_locks[9]=LOCK_ADDR (bus_datas); global_locks[10]=LOCK_ADDR (shutdown_funcs); global_locks[11]=LOCK_ADDR (system_users); global_locks[12]=LOCK_ADDR (message_cache); global_locks[13]=LOCK_ADDR (shared_connections); global_locks[14]=LOCK_ADDR (machine_uuid); #undef LOCK_ADDR #endif _dbus_assert (_DBUS_N_ELEMENTS (global_locks) == _DBUS_N_GLOBAL_LOCKS); i = 0; dynamic_global_locks = dbus_new (DBusMutex**, _DBUS_N_GLOBAL_LOCKS); if (dynamic_global_locks == NULL) goto failed; while (i < _DBUS_N_ELEMENTS (global_locks)) { *global_locks[i] = _dbus_mutex_new (); if (*global_locks[i] == NULL) goto failed; dynamic_global_locks[i] = global_locks[i]; ++i; } if (!_dbus_register_shutdown_func (shutdown_global_locks, dynamic_global_locks)) goto failed; if (!init_uninitialized_locks ()) goto failed; return TRUE; failed: dbus_free (dynamic_global_locks); for (i = i - 1; i >= 0; i--) { _dbus_mutex_free (*global_locks[i]); *global_locks[i] = NULL; } return FALSE; }