int supplicant_dbus_method_call(const char *path, const char *interface, const char *method, supplicant_dbus_setup_function setup, supplicant_dbus_result_function function, void *user_data) { struct method_call_data *data; DBusMessage *message; DBusMessageIter iter; DBusPendingCall *call; if (connection == NULL) return -EINVAL; if (path == NULL || interface == NULL || method == NULL) return -EINVAL; data = dbus_malloc0(sizeof(*data)); if (data == NULL) return -ENOMEM; message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path, interface, method); if (message == NULL) { dbus_free(data); return -ENOMEM; } dbus_message_set_auto_start(message, FALSE); dbus_message_iter_init_append(message, &iter); if (setup != NULL) setup(&iter, user_data); if (dbus_connection_send_with_reply(connection, message, &call, TIMEOUT) == FALSE) { dbus_message_unref(message); dbus_free(data); return -EIO; } if (call == NULL) { dbus_message_unref(message); dbus_free(data); return -EIO; } data->function = function; data->user_data = user_data; dbus_pending_call_set_notify(call, method_call_reply, data, dbus_free); dbus_message_unref(message); return 0; }
int supplicant_dbus_property_get(const char *path, const char *interface, const char *method, supplicant_dbus_property_function function, void *user_data) { struct property_get_data *data; DBusMessage *message; DBusPendingCall *call; if (connection == NULL) return -EINVAL; if (path == NULL || interface == NULL || method == NULL) return -EINVAL; data = dbus_malloc0(sizeof(*data)); if (data == NULL) return -ENOMEM; message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path, DBUS_INTERFACE_PROPERTIES, "Get"); if (message == NULL) { dbus_free(data); return -ENOMEM; } dbus_message_set_auto_start(message, FALSE); dbus_message_append_args(message, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &method, NULL); if (dbus_connection_send_with_reply(connection, message, &call, TIMEOUT) == FALSE) { dbus_message_unref(message); dbus_free(data); return -EIO; } if (call == NULL) { dbus_message_unref(message); dbus_free(data); return -EIO; } data->function = function; data->user_data = user_data; dbus_pending_call_set_notify(call, property_get_reply, data, dbus_free); dbus_message_unref(message); return 0; }
int supplicant_dbus_property_set(const char *path, const char *interface, const char *key, const char *signature, supplicant_dbus_setup_function setup, supplicant_dbus_result_function function, void *user_data) { struct property_set_data *data; DBusMessage *message; DBusMessageIter iter, value; DBusPendingCall *call; if (connection == NULL) return -EINVAL; if (path == NULL || interface == NULL) return -EINVAL; if (key == NULL || signature == NULL || setup == NULL) return -EINVAL; data = dbus_malloc0(sizeof(*data)); if (data == NULL) return -ENOMEM; message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path, DBUS_INTERFACE_PROPERTIES, "Set"); if (message == NULL) { dbus_free(data); return -ENOMEM; } dbus_message_set_auto_start(message, FALSE); dbus_message_iter_init_append(message, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key); dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, signature, &value); setup(&value, user_data); dbus_message_iter_close_container(&iter, &value); if (dbus_connection_send_with_reply(connection, message, &call, TIMEOUT) == FALSE) { dbus_message_unref(message); dbus_free(data); return -EIO; } if (call == NULL) { dbus_message_unref(message); dbus_free(data); return -EIO; } data->function = function; data->user_data = user_data; dbus_pending_call_set_notify(call, property_set_reply, data, dbus_free); dbus_message_unref(message); return 0; }
static void time_for_size (int size) { int i; int j; clock_t start; clock_t end; #define FREE_ARRAY_SIZE 512 #define N_ITERATIONS FREE_ARRAY_SIZE * 512 void *to_free[FREE_ARRAY_SIZE]; DBusMemPool *pool; _dbus_verbose ("Timings for size %d\n", size); _dbus_verbose (" malloc\n"); start = clock (); i = 0; j = 0; while (i < N_ITERATIONS) { to_free[j] = dbus_malloc (size); _dbus_assert (to_free[j] != NULL); /* in a real app of course this is wrong */ ++j; if (j == FREE_ARRAY_SIZE) { j = 0; while (j < FREE_ARRAY_SIZE) { dbus_free (to_free[j]); ++j; } j = 0; } ++i; } end = clock (); _dbus_verbose (" created/destroyed %d elements in %g seconds\n", N_ITERATIONS, (end - start) / (double) CLOCKS_PER_SEC); _dbus_verbose (" mempools\n"); start = clock (); pool = _dbus_mem_pool_new (size, FALSE); i = 0; j = 0; while (i < N_ITERATIONS) { to_free[j] = _dbus_mem_pool_alloc (pool); _dbus_assert (to_free[j] != NULL); /* in a real app of course this is wrong */ ++j; if (j == FREE_ARRAY_SIZE) { j = 0; while (j < FREE_ARRAY_SIZE) { _dbus_mem_pool_dealloc (pool, to_free[j]); ++j; } j = 0; } ++i; } _dbus_mem_pool_free (pool); end = clock (); _dbus_verbose (" created/destroyed %d elements in %g seconds\n", N_ITERATIONS, (end - start) / (double) CLOCKS_PER_SEC); _dbus_verbose (" zeroed malloc\n"); start = clock (); i = 0; j = 0; while (i < N_ITERATIONS) { to_free[j] = dbus_malloc0 (size); _dbus_assert (to_free[j] != NULL); /* in a real app of course this is wrong */ ++j; if (j == FREE_ARRAY_SIZE) { j = 0; while (j < FREE_ARRAY_SIZE) { dbus_free (to_free[j]); ++j; } j = 0; } ++i; } end = clock (); _dbus_verbose (" created/destroyed %d elements in %g seconds\n", N_ITERATIONS, (end - start) / (double) CLOCKS_PER_SEC); _dbus_verbose (" zeroed mempools\n"); start = clock (); pool = _dbus_mem_pool_new (size, TRUE); i = 0; j = 0; while (i < N_ITERATIONS) { to_free[j] = _dbus_mem_pool_alloc (pool); _dbus_assert (to_free[j] != NULL); /* in a real app of course this is wrong */ ++j; if (j == FREE_ARRAY_SIZE) { j = 0; while (j < FREE_ARRAY_SIZE) { _dbus_mem_pool_dealloc (pool, to_free[j]); ++j; } j = 0; } ++i; } _dbus_mem_pool_free (pool); end = clock (); _dbus_verbose (" created/destroyed %d elements in %g seconds\n", N_ITERATIONS, (end - start) / (double) CLOCKS_PER_SEC); }
/** * Allocates an object from the memory pool. * The object must be freed with _dbus_mem_pool_dealloc(). * * @param pool the memory pool * @returns the allocated object or #NULL if no memory. */ void* _dbus_mem_pool_alloc (DBusMemPool *pool) { #ifdef DBUS_BUILD_TESTS if (_dbus_disable_mem_pools ()) { DBusMemBlock *block; int alloc_size; /* This is obviously really silly, but it's * debug-mode-only code that is compiled out * when tests are disabled (_dbus_disable_mem_pools() * is a constant expression FALSE so this block * should vanish) */ alloc_size = sizeof (DBusMemBlock) - ELEMENT_PADDING + pool->element_size; if (pool->zero_elements) block = dbus_malloc0 (alloc_size); else block = dbus_malloc (alloc_size); if (block != NULL) { block->next = pool->blocks; pool->blocks = block; pool->allocated_elements += 1; return (void*) &block->elements[0]; } else return NULL; } else #endif { if (_dbus_decrement_fail_alloc_counter ()) { _dbus_verbose (" FAILING mempool alloc\n"); return NULL; } else if (pool->free_elements) { DBusFreedElement *element = pool->free_elements; pool->free_elements = pool->free_elements->next; if (pool->zero_elements) memset (element, '\0', pool->element_size); pool->allocated_elements += 1; return element; } else { void *element; if (pool->blocks == NULL || pool->blocks->used_so_far == pool->block_size) { /* Need a new block */ DBusMemBlock *block; int alloc_size; #ifdef DBUS_BUILD_TESTS int saved_counter; #endif if (pool->block_size <= _DBUS_INT_MAX / 4) /* avoid overflow */ { /* use a larger block size for our next block */ pool->block_size *= 2; _dbus_assert ((pool->block_size % pool->element_size) == 0); } alloc_size = sizeof (DBusMemBlock) - ELEMENT_PADDING + pool->block_size; #ifdef DBUS_BUILD_TESTS /* We save/restore the counter, so that memory pools won't * cause a given function to have different number of * allocations on different invocations. i.e. when testing * we want consistent alloc patterns. So we skip our * malloc here for purposes of failed alloc simulation. */ saved_counter = _dbus_get_fail_alloc_counter (); _dbus_set_fail_alloc_counter (_DBUS_INT_MAX); #endif if (pool->zero_elements) block = dbus_malloc0 (alloc_size); else block = dbus_malloc (alloc_size); #ifdef DBUS_BUILD_TESTS _dbus_set_fail_alloc_counter (saved_counter); _dbus_assert (saved_counter == _dbus_get_fail_alloc_counter ()); #endif if (block == NULL) return NULL; block->used_so_far = 0; block->next = pool->blocks; pool->blocks = block; } element = &pool->blocks->elements[pool->blocks->used_so_far]; pool->blocks->used_so_far += pool->element_size; pool->allocated_elements += 1; return element; } } }