static dbus_bool_t _dbus_condvar_wait_win32 (DBusCondVar *cond, DBusMutex *mutex, int milliseconds) { DWORD retval; dbus_bool_t ret; HANDLE event = TlsGetValue (dbus_cond_event_tls); if (!event) { event = CreateEvent (0, FALSE, FALSE, NULL); if (event == 0) return FALSE; TlsSetValue (dbus_cond_event_tls, event); } EnterCriticalSection (&cond->lock); /* The event must not be signaled. Check this */ _dbus_assert (WaitForSingleObject (event, 0) == WAIT_TIMEOUT); ret = _dbus_list_append (&cond->list, event); LeaveCriticalSection (&cond->lock); if (!ret) return FALSE; /* Prepend failed */ _dbus_mutex_unlock (mutex); retval = WaitForSingleObject (event, milliseconds); _dbus_mutex_lock (mutex); if (retval == WAIT_TIMEOUT) { EnterCriticalSection (&cond->lock); _dbus_list_remove (&cond->list, event); /* In the meantime we could have been signaled, so we must again * wait for the signal, this time with no timeout, to reset * it. retval is set again to honour the late arrival of the * signal */ retval = WaitForSingleObject (event, 0); LeaveCriticalSection (&cond->lock); } #ifndef DBUS_DISABLE_ASSERT EnterCriticalSection (&cond->lock); /* Now event must not be inside the array, check this */ _dbus_assert (_dbus_list_remove (&cond->list, event) == FALSE); LeaveCriticalSection (&cond->lock); #endif /* !G_DISABLE_ASSERT */ return retval != WAIT_TIMEOUT; }
void _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p) { _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); _dbus_assert (allocator->allocated_slots[*slot_id_p].refcount > 0); allocator->allocated_slots[*slot_id_p].refcount -= 1; if (allocator->allocated_slots[*slot_id_p].refcount > 0) { _dbus_mutex_unlock (*(allocator->lock_loc)); return; } /* refcount is 0, free the slot */ _dbus_verbose ("Freeing slot %d on allocator %p total %d allocated %d used\n", *slot_id_p, allocator, allocator->n_allocated_slots, allocator->n_used_slots); allocator->allocated_slots[*slot_id_p].slot_id = -1; *slot_id_p = -1; allocator->n_used_slots -= 1; if (allocator->n_used_slots == 0) { DBusMutex **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); } else { _dbus_mutex_unlock (*(allocator->lock_loc)); } }
dbus_bool_t _dbus_data_slot_list_set (DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot, void *data, DBusFreeFunction free_data_func, DBusFreeFunction *old_free_func, void **old_data) { #ifndef DBUS_DISABLE_ASSERT /* We need to take the allocator lock here, because the allocator could * 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_assert (slot < allocator->n_allocated_slots); _dbus_assert (allocator->allocated_slots[slot].slot_id == slot); _dbus_mutex_unlock (*(allocator->lock_loc)); #endif if (slot >= list->n_slots) { DBusDataSlot *tmp; int i; tmp = dbus_realloc (list->slots, sizeof (DBusDataSlot) * (slot + 1)); if (tmp == NULL) return FALSE; list->slots = tmp; i = list->n_slots; list->n_slots = slot + 1; while (i < list->n_slots) { list->slots[i].data = NULL; list->slots[i].free_data_func = NULL; ++i; } } _dbus_assert (slot < list->n_slots); *old_data = list->slots[slot].data; *old_free_func = list->slots[slot].free_data_func; list->slots[slot].data = data; list->slots[slot].free_data_func = free_data_func; return TRUE; }
void* _dbus_data_slot_list_get (DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot) { #ifndef DBUS_DISABLE_ASSERT /* We need to take the allocator lock here, because the allocator could * 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_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)); #endif if (slot >= list->n_slots) return NULL; else return list->slots[slot].data; }
dbus_bool_t _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator, DBusMutex **mutex_loc, dbus_int32_t *slot_id_p) { dbus_int32_t slot; _dbus_mutex_lock (*mutex_loc); if (allocator->n_allocated_slots == 0) { _dbus_assert (allocator->lock_loc == NULL); allocator->lock_loc = mutex_loc; } else if (allocator->lock_loc != mutex_loc) { _dbus_warn_check_failed ("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.\n"); _dbus_assert_not_reached ("exiting"); } if (*slot_id_p >= 0) { slot = *slot_id_p; _dbus_assert (slot < allocator->n_allocated_slots); _dbus_assert (allocator->allocated_slots[slot].slot_id == slot); allocator->allocated_slots[slot].refcount += 1; goto out; } _dbus_assert (*slot_id_p < 0); if (allocator->n_used_slots < allocator->n_allocated_slots) { slot = 0; while (slot < allocator->n_allocated_slots) { if (allocator->allocated_slots[slot].slot_id < 0) { allocator->allocated_slots[slot].slot_id = slot; allocator->allocated_slots[slot].refcount = 1; allocator->n_used_slots += 1; break; } ++slot; } _dbus_assert (slot < allocator->n_allocated_slots); } else { DBusAllocatedSlot *tmp; slot = -1; tmp = dbus_realloc (allocator->allocated_slots, sizeof (DBusAllocatedSlot) * (allocator->n_allocated_slots + 1)); if (tmp == NULL) goto out; allocator->allocated_slots = tmp; slot = allocator->n_allocated_slots; allocator->n_allocated_slots += 1; allocator->n_used_slots += 1; allocator->allocated_slots[slot].slot_id = slot; allocator->allocated_slots[slot].refcount = 1; } _dbus_assert (slot >= 0); _dbus_assert (slot < allocator->n_allocated_slots); _dbus_assert (*slot_id_p < 0); _dbus_assert (allocator->allocated_slots[slot].slot_id == slot); _dbus_assert (allocator->allocated_slots[slot].refcount == 1); *slot_id_p = slot; _dbus_verbose ("Allocated slot %d on allocator %p total %d slots allocated %d used\n", slot, allocator, allocator->n_allocated_slots, allocator->n_used_slots); out: _dbus_mutex_unlock (*(allocator->lock_loc)); return slot >= 0; }