void manager_free(Manager *m) { Machine *machine; Image *i; assert(m); while ((machine = hashmap_first(m->machines))) machine_free(machine); hashmap_free(m->machines); hashmap_free(m->machine_units); hashmap_free(m->machine_leaders); while ((i = hashmap_steal_first(m->image_cache))) image_unref(i); hashmap_free(m->image_cache); sd_event_source_unref(m->image_cache_defer_event); bus_verify_polkit_async_registry_free(m->polkit_registry); sd_bus_unref(m->bus); sd_event_unref(m->event); free(m); }
/** * This function deletes number of entries from list specified by range * * \param group image group from which we will remove records * \param range range specifying entries * \return OK on success */ RCode group_delete_range(ImageGroup* group, Range range) { guint i = 0; ASSERT(NULL != group); ASSERT(NULL != group->list); TRACE_MESSAGE(IGRP, TL_INFO, "Removing range (group='%s',range=<%d,%d>)", group->name, range.start, range.end ); // check if index is in range if ( FAIL == range_check_bounds(range, 0, group->list->len - 1) ) { ERROR_SET(ERROR.OUT_OF_RANGE); ERROR_NOTE("Supplied range is out of bounds (group='%s',range=<%d,%d>,min=0,max=%d)", group->name, range.start,range.end,group->list->len-1 ); return FAIL; } // unreference images that will be removed for (i = range.start; i <= range.end; i++) { ImageGroupRecord record = g_array_index(group->list, ImageGroupRecord, i); /** \todo Check what to do with the call return code */ image_unref(record.image); } group->list = g_array_remove_range(group->list, range.start, range.end - range.start + 1); return OK; }
/** * This function deallocates all memory allocated for image list. * * \param group pointer to image list to deallocate * \return OK on success */ RCode group_destroy(ImageGroup* group) { RCode result; guint i; ASSERT( NULL != group); ASSERT( NULL != group->list); TRACE_MESSAGE(IGRP, TL_MINOR, "Destroying group (name='%s',tag='%c')", group->name, group->tag); // unreference all images that are stored in the buffer for (i = 0; i < group->list->len; i++ ) { ImageGroupRecord* record = &g_array_index(group->list, ImageGroupRecord, i); result = taglist_remove(image_get_groups(record->image), group->tag); if ( FAIL == result ) { ERROR_LOG(); } result = image_unref(record->image); if ( FAIL == result ) { ERROR_LOG(); } } g_array_free(group->list, TRUE); g_free( (gpointer)group->name); g_free( (gpointer)group); return OK; }
/* * load_sprite_images() * Loads the sprite by reading the spritesheet */ void load_sprite_images(spriteinfo_t *spr) { int i, cur_x, cur_y; image_t *sheet; spr->frame_count = (spr->rect_w / spr->frame_w) * (spr->rect_h / spr->frame_h); spr->frame_data = mallocx(spr->frame_count * sizeof(*(spr->frame_data))); /* reading the images... */ if(NULL == (sheet = image_load(spr->source_file))) fatal_error("FATAL ERROR: couldn't load spritesheet \"%s\"", spr->source_file); cur_x = spr->rect_x; cur_y = spr->rect_y; for(i=0; i<spr->frame_count; i++) { spr->frame_data[i] = image_create_shared(sheet, cur_x, cur_y, spr->frame_w, spr->frame_h); cur_x += spr->frame_w; if(cur_x >= spr->rect_x+spr->rect_w) { cur_x = spr->rect_x; cur_y += spr->frame_h; } } image_unref(spr->source_file); }
/** * The function will deallocate all Image structures which are referenced only * from pile (ie having ref == 1 ) in pile and remove them from list. * * In case some Image structure is referenced not only from pile, function will * terminate prematurely and return error. Invocation can be repeated when all * references to the structure are removed. * * \return OK on success */ RCode pile_destroy() { GList* iterator = NULL; if ( NULL == pile_list_head ) { // no need to destroy empty pile return OK; } iterator = g_list_first(pile_list_head); while ( NULL != iterator ) { TRACE_MESSAGE(PILE, TL_DEBUG, "Deallocating %s", ((Image*)iterator->data)->name); if ( FAIL == image_unref((Image*)iterator->data) ) { ERROR_NOTE("Unable to deallocate image structure"); // attempt to leave image list in consistent state after failing to // free Image structure. Remove all elements of list which do not // point to Image structure anymore (ie previously freed) pile_list_head = g_list_remove_all(pile_list_head, NULL); return FAIL; } iterator->data = NULL; iterator = g_list_next(iterator); } TRACE_MESSAGE(PILE, TL_DEBUG, "Freeing image pile list"); g_list_free(pile_list_head); // This needs to be here since freed list elements are returned to glib // allocator but remain valid! So it will look as if we have one more // element in list. pile_list_head = NULL; return OK; }
int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { _cleanup_free_ char *e = NULL; Manager *m = userdata; Image *image = NULL; const char *p; int r; assert(bus); assert(path); assert(interface); assert(found); p = startswith(path, "/org/freedesktop/machine1/image/"); if (!p) return 0; e = bus_label_unescape(p); if (!e) return -ENOMEM; image = hashmap_get(m->image_cache, e); if (image) { *found = image; return 1; } r = hashmap_ensure_allocated(&m->image_cache, &string_hash_ops); if (r < 0) return r; if (!m->image_cache_defer_event) { r = sd_event_add_defer(m->event, &m->image_cache_defer_event, image_flush_cache, m); if (r < 0) return r; r = sd_event_source_set_priority(m->image_cache_defer_event, SD_EVENT_PRIORITY_IDLE); if (r < 0) return r; } r = sd_event_source_set_enabled(m->image_cache_defer_event, SD_EVENT_ONESHOT); if (r < 0) return r; r = image_find(e, &image); if (r <= 0) return r; image->userdata = m; r = hashmap_put(m->image_cache, image->name, image); if (r < 0) { image_unref(image); return r; } *found = image; return 1; }
static int image_flush_cache(sd_event_source *s, void *userdata) { Manager *m = userdata; Image *i; assert(s); assert(m); while ((i = hashmap_steal_first(m->image_cache))) image_unref(i); return 0; }
/** * \brief Tear down test related structures after the test finished. * * Deallocate test group and all test image structures. */ static void group_teardown(void) { int i; COLOR_TEARDOWN_START; // destroy test image group and its content group_destroy(image_group); group_buffer_destroy(); if ( error_is_error() ) ERROR_LOG(); // destroy temporary image structures for (i = 0; i < 10; i++) { image_unref(pointer_list[i]); pointer_list[i] = NULL; if ( error_is_error() ) ERROR_LOG(); } COLOR_TEARDOWN_END; return ; }
static int property_handle_net_wm_icon(void *data, xcb_connection_t *connection, uint8_t state, xcb_window_t window, xcb_atom_t name, xcb_get_property_reply_t *reply) { client_t *c = client_getbywin(window); if(c) { image_t *icon; image_unref(&c->icon); icon = ewmh_window_icon_from_reply(reply); c->icon = icon ? image_ref(&icon) : NULL; /* execute hook */ hooks_property(c, "icon"); } return 0; }
/** * The function deletes one image from the image group array using supplied * index. * * \param group image group from which image will be removed * \param index index of the image to remove * \return OK on success */ RCode group_delete_index(ImageGroup* group, guint index) { ImageGroupRecord record; ASSERT(NULL != group); ASSERT(NULL != group->list); TRACE_MESSAGE(IGRP, TL_INFO, "Removing index (group='%s',index=%d)", group->name, index); if ( 0 > index || group->list->len - 1 < index ) { ERROR_SET(ERROR.OUT_OF_RANGE); ERROR_NOTE("Supplied index is out of bounds (group='%s',index=%d,min=0,max=%d)", group->name, index, group->list->len - 1 ); return FAIL; } // unreference images that will be removed record = g_array_index(group->list, ImageGroupRecord, index); /** \todo Check what to do with the call return code */ image_unref(record.image); group->list = g_array_remove_range(group->list, index, 1); return OK; }