if (im->flags.lru) return;
_evas_cache_image_dirty_del(im);
_evas_cache_image_activ_del(im);
- _evas_cache_image_lru_nodata_del(im);
+ _evas_cache_image_lru_nodata_del(im);
if (!im->cache_key) return;
im->flags.lru = 1;
im->flags.cached = 1;
if (im->flags.given_mmap)
- {
- eina_hash_direct_add(im->cache->mmap_inactiv, im->cache_key, im);
- }
+ eina_hash_direct_add(im->cache->mmap_inactiv, im->cache_key, im);
else
- {
- eina_hash_direct_add(im->cache->inactiv, im->cache_key, im);
- }
+ eina_hash_direct_add(im->cache->inactiv, im->cache_key, im);
im->cache->lru = eina_inlist_prepend(im->cache->lru, EINA_INLIST_GET(im));
im->cache->usage += im->cache->func.mem_size_get(im);
}
im->flags.lru = 0;
im->flags.cached = 0;
if (im->flags.given_mmap)
- {
- eina_hash_del(im->cache->mmap_inactiv, im->cache_key, im);
- }
+ eina_hash_del(im->cache->mmap_inactiv, im->cache_key, im);
else
- {
- eina_hash_del(im->cache->inactiv, im->cache_key, im);
- }
+ eina_hash_del(im->cache->inactiv, im->cache_key, im);
im->cache->lru = eina_inlist_remove(im->cache->lru, EINA_INLIST_GET(im));
im->cache->usage -= im->cache->func.mem_size_get(im);
}
Image_Entry_Task *task;
if (!ie) return;
+//// SLKL(ie->lock);
+//// SLKU(ie->lock);
if ((cache) && (cache->func.debug)) cache->func.debug("deleting", ie);
if (ie->flags.delete_me == 1) return;
if (ie->preload)
evas_cache_image_cancelled(void *data)
{
Image_Entry *current = data;
+ Eina_Bool ret;
- return evas_preload_thread_cancelled_is(current->preload);
+ evas_cache_image_ref(current);
+ ret = evas_preload_thread_cancelled_is(current->preload);
+ evas_cache_image_drop(current);
+ return ret;
}
static void
Image_Entry_Task *task;
Evas_Cache_Target *tmp;
+ evas_cache_image_ref(ie);
ie->cache->preload = eina_list_remove(ie->cache->preload, ie);
ie->cache->pending = eina_list_remove(ie->cache->pending, ie);
ie->preload = NULL;
ie->flags.preload_pending = 0;
- evas_cache_image_ref(ie);
while ((tmp = ie->targets))
{
ie->targets = (Evas_Cache_Target *)
Evas_Cache_Image *cache = NULL;
Image_Entry *ie = (Image_Entry *)data;
+ evas_cache_image_ref(ie);
ie->preload = NULL;
ie->cache->pending = eina_list_remove(ie->cache->pending, ie);
if ((ie->flags.delete_me) || (ie->flags.dirty))
{
ie->flags.delete_me = 0;
+ evas_cache_image_drop(ie);
+ SLKL(engine_lock);
_evas_cache_image_entry_delete(ie->cache, ie);
+ SLKU(engine_lock);
return;
}
SLKL(ie->lock_task);
SLKU(ie->lock_task);
if (ie->references == 0)
{
+ SLKL(engine_lock);
_evas_cache_image_lru_add(ie);
+ SLKU(engine_lock);
cache = ie->cache;
}
if (ie->flags.loaded) _evas_cache_image_async_end(ie);
+ evas_cache_image_drop(ie);
if (cache) evas_cache_image_flush(cache);
}
Evas_Cache_Target *tg;
Image_Entry_Task *task;
- if (ie->flags.preload_done) return 0;
+ evas_cache_image_ref(ie);
+ if (ie->flags.preload_done)
+ {
+ evas_cache_image_drop(ie);
+ return 0;
+ }
tg = calloc(1, sizeof(Evas_Cache_Target));
if (!tg) return 0;
_evas_cache_image_async_cancel,
ie);
}
+ evas_cache_image_drop(ie);
return 1;
}
Eina_List *l;
Image_Entry_Task *task;
+// evas_cache_image_ref(ie);
if (target)
{
SLKL(ie->lock_task);
ie->flags.pending = 1;
evas_preload_thread_cancel(ie->preload);
}
+// evas_cache_image_drop(ie);
}
EAPI int
}
evas_async_events_process();
+ SLKL(engine_lock);
EINA_INLIST_FREE(cache->lru, im)
_evas_cache_image_entry_delete(cache, im);
EINA_INLIST_FREE(cache->lru_nodata, im)
_evas_cache_image_entry_delete(cache, im);
}
delete_list = NULL;
+
eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list);
eina_hash_foreach(cache->mmap_activ, _evas_cache_image_free_cb, &delete_list);
while (delete_list)
_evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list));
delete_list = eina_list_remove_list(delete_list, delete_list);
}
+ SLKU(engine_lock);
/* Now wait for all pending image to die */
while (cache->pending)
/* find image by key in active mmap hash */
+ SLKL(engine_lock);
im = eina_hash_find(cache->mmap_activ, hkey);
if ((im) && (!im->load_failed)) goto on_ok;
else if ((im) && (im->load_failed))
}
im = _evas_cache_image_entry_new(cache, hkey, NULL, f, NULL, key, lo, error);
- if (!im) return NULL;
+ if (!im)
+ {
+ SLKU(engine_lock);
+ return NULL;
+ }
on_ok:
*error = EVAS_LOAD_ERROR_NONE;
+//// SLKL(im->lock);
im->references++;
+//// SLKU(im->lock);
+ SLKU(engine_lock);
return im;
}
tlo.skip_head = skip;
/* find image by key in active hash */
+ SLKL(engine_lock);
im = eina_hash_find(cache->activ, hkey);
if ((im) && (!im->load_failed))
{
on_ok:
*error = EVAS_LOAD_ERROR_NONE;
+//// SLKL(im->lock);
im->references++;
+//// SLKU(im->lock);
+ SLKU(engine_lock);
return im;
on_stat_error:
else
*error = EVAS_LOAD_ERROR_GENERIC;
+ SLKU(engine_lock);
return NULL;
}
EAPI void
evas_cache_image_ref(Image_Entry *im)
{
+ SLKL(engine_lock);
+//// SLKL(im->lock);
im->references++;
+//// SLKU(im->lock);
+ SLKU(engine_lock);
}
EAPI void
Evas_Cache_Image *cache;
int references;
+ SLKL(engine_lock);
+//// SLKL(im->lock);
im->references--;
if (im->references < 0) im->references = 0;
references = im->references;
+//// SLKU(im->lock);
+ SLKU(engine_lock);
cache = im->cache;
}
if ((im->flags.dirty) || (im->load_failed))
{
+ SLKL(engine_lock);
_evas_cache_image_entry_delete(cache, im);
+ SLKU(engine_lock);
return;
}
if (cache)
{
+ SLKL(engine_lock);
_evas_cache_image_lru_add(im);
+ SLKU(engine_lock);
evas_cache_image_flush(cache);
}
}
references = im->references;
if (references > 1) return;
if ((im->flags.dirty) || (!im->flags.need_data)) return;
+ SLKL(engine_lock);
_evas_cache_image_lru_nodata_add(im);
+ SLKU(engine_lock);
}
EAPI Image_Entry *
im_dirty->references = 1;
evas_cache_image_drop(im);
}
+ SLKL(engine_lock);
_evas_cache_image_dirty_add(im_dirty);
+ SLKU(engine_lock);
}
if (cache->func.debug) cache->func.debug("dirty-region", im_dirty);
if (references <= 1)
{
+ SLKL(engine_lock);
if (!im->flags.dirty) _evas_cache_image_dirty_add(im);
+ SLKU(engine_lock);
}
else
{
(cspace == EVAS_COLORSPACE_YCBCR422601_PL))
w &= ~0x1;
+ SLKL(engine_lock);
im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err);
+ SLKU(engine_lock);
if (!im) return NULL;
im->space = cspace;
im->flags.alpha = alpha;
_evas_cache_image_entry_surface_alloc(cache, im, w, h);
if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0)
{
+ SLKL(engine_lock);
_evas_cache_image_entry_delete(cache, im);
+ SLKU(engine_lock);
return NULL;
}
im->references = 1;
(cspace == EVAS_COLORSPACE_YCBCR422601_PL))
w &= ~0x1;
+ SLKL(engine_lock);
im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err);
+ SLKU(engine_lock);
if (!im) return NULL;
im->w = w;
im->h = h;
im->flags.alpha = alpha;
if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0)
{
+ SLKL(engine_lock);
_evas_cache_image_entry_delete(cache, im);
+ SLKU(engine_lock);
return NULL;
}
im->references = 1;
Image_Entry *im2 = NULL;
int error;
+ evas_cache_image_ref(im);
if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
(im->space == EVAS_COLORSPACE_YCBCR422P709_PL) ||
(im->space == EVAS_COLORSPACE_YCBCR422601_PL))
w &= ~0x1;
- if ((im->w == w) && (im->h == h)) return im;
+ if ((im->w == w) && (im->h == h))
+ {
+ evas_cache_image_drop(im);
+ return im;
+ }
cache = im->cache;
+ SLKL(engine_lock);
im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &error);
+ SLKU(engine_lock);
if (!im2) goto on_error;
im2->flags.alpha = im->flags.alpha;
im2->flags.loaded = EINA_TRUE;
evas_cache_image_drop(im);
if (cache->func.debug) cache->func.debug("size_set", im2);
+ evas_cache_image_drop(im);
return im2;
on_error:
+ SLKL(engine_lock);
if (im2) _evas_cache_image_entry_delete(cache, im2);
+ SLKU(engine_lock);
+ evas_cache_image_drop(im);
evas_cache_image_drop(im);
return NULL;
}
Eina_Bool preload = EINA_FALSE;
int error = EVAS_LOAD_ERROR_NONE;
- if ((im->flags.loaded) && (!im->animated.animated)) return error;
+ evas_cache_image_ref(im);
+ if ((im->flags.loaded) && (!im->animated.animated))
+ {
+ evas_cache_image_drop(im);
+ return error;
+ }
evas_common_rgba_pending_unloads_remove(im);
if (im->preload)
{
}
}
- if ((im->flags.loaded) && (!im->animated.animated)) return error;
+ if ((im->flags.loaded) && (!im->animated.animated))
+ {
+ evas_cache_image_drop(im);
+ return error;
+ }
SLKL(im->lock);
im->flags.in_progress = EINA_TRUE;
im->flags.loaded = 0;
}
if (preload) _evas_cache_image_async_end(im);
+ evas_cache_image_drop(im);
return error;
}
EAPI void
evas_cache_image_unload_data(Image_Entry *im)
{
- if (im->flags.in_progress) return;
+ evas_cache_image_ref(im);
+ if (im->flags.in_progress)
+ {
+ evas_cache_image_drop(im);
+ return;
+ }
evas_cache_image_preload_cancel(im, NULL);
-
+
if (SLKT(im->lock) == EINA_FALSE) /* can't get image lock - busy async load */
{
SLKL(im->lock_cancel);
im->flags.unload_cancel = EINA_TRUE;
SLKU(im->lock_cancel);
+ evas_cache_image_drop(im);
return;
}
{
SLKU(im->lock_cancel);
SLKU(im->lock);
+ evas_cache_image_drop(im);
return;
}
SLKU(im->lock_cancel);
im->cache->func.destructor(im);
SLKU(im->lock);
+ evas_cache_image_drop(im);
//FIXME: imagedataunload - inform owners
}
{
Image_Entry *im;
+// _evas_cache_image_unload_cb -> evas_cache_image_unload_data -> evas_cache_image_ref
+// deadlock
+////// SLKL(engine_lock);
EINA_INLIST_FOREACH(cache->lru, im) evas_cache_image_unload_data(im);
EINA_INLIST_FOREACH(cache->lru_nodata, im) evas_cache_image_unload_data(im);
eina_hash_foreach(cache->activ, _evas_cache_image_unload_cb, NULL);
eina_hash_foreach(cache->inactiv, _evas_cache_image_unload_cb, NULL);
+////// SLKU(engine_lock);
}
static int async_frozen = 0;
{
RGBA_Image *img = (RGBA_Image *)im;
+ evas_cache_image_ref(im);
if (((int)im->w > 0) && ((int)im->h > 0) &&
(((im->flags.loaded) && (img->image.data)) ||
(im->flags.textured && !im->flags.updated_data)))
free(tmp);
}
evas_object_inform_call_image_preloaded((Evas_Object*)target);
+ evas_cache_image_drop(im);
return;
}
im->flags.loaded = 0;
if (!_evas_cache_image_entry_preload_add(im, target, func, engine_data, custom_data))
evas_object_inform_call_image_preloaded((Evas_Object*) target);
+ evas_cache_image_drop(im);
}
EAPI void
evas_cache_image_preload_cancel(Image_Entry *im, const Eo *target)
{
if (!target) return;
+ evas_cache_image_ref(im);
_evas_cache_image_entry_preload_remove(im, target);
+ evas_cache_image_drop(im);
}
#ifdef CACHEDUMP
cache->limit / 1024);
printf("................................................................\n");
total = 0;
+ SLKL(engine_lock);
EINA_INLIST_FOREACH(cache->lru_nodata, im)
_dump_img(im, "NODATA");
EINA_INLIST_FOREACH(cache->lru, im)
total,
cache->usage);
eina_hash_foreach(cache->activ, _dump_cache_active, NULL);
+ SLKU(engine_lock);
}
#endif
#endif
if (cache->limit == (unsigned int)-1) return -1;
+ SLKL(engine_lock);
while ((cache->lru) && (cache->limit < (unsigned int)cache->usage))
{
Image_Entry *im;
cache->func.surface_delete(im);
im->flags.loaded = 0;
}
+ SLKU(engine_lock);
return cache->usage;
}
int err;
Image_Entry *im;
+ SLKL(engine_lock);
im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err);
+ SLKU(engine_lock);
if (!im) return NULL;
im->references = 1;
return im;
EAPI void
evas_cache_image_colorspace(Image_Entry *im, Evas_Colorspace cspace)
{
- if (im->space == cspace) return;
+ evas_cache_image_ref(im);
+ if (im->space == cspace) goto done;
im->space = cspace;
- if (!im->cache) return;
+ if (!im->cache) goto done;
im->cache->func.color_space(im, cspace);
+done:
+ evas_cache_image_drop(im);
}
EAPI void *
evas_cache_private_from_image_entry_get(Image_Entry *im)
{
- return (void *)im->cache->data;
+ void *data;
+ evas_cache_image_ref(im);
+ data = (void *)im->cache->data;
+ evas_cache_image_drop(im);
+ return data;
}
EAPI void *