evas image cache - add lots more locking to try stamp out any thread bug

this definitely fixes T5223 because it adds an engine lock around the
code segemtnt that does compare time stamps... and hopefulyl a few
more things too.

@fix
This commit is contained in:
Carsten Haitzler 2017-03-09 11:18:32 +09:00
parent 1a5563ab63
commit d550190d6b
1 changed files with 131 additions and 25 deletions

View File

@ -109,18 +109,14 @@ _evas_cache_image_lru_add(Image_Entry *im)
if (im->flags.lru) return; if (im->flags.lru) return;
_evas_cache_image_dirty_del(im); _evas_cache_image_dirty_del(im);
_evas_cache_image_activ_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; if (!im->cache_key) return;
im->flags.lru = 1; im->flags.lru = 1;
im->flags.cached = 1; im->flags.cached = 1;
if (im->flags.given_mmap) 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 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->lru = eina_inlist_prepend(im->cache->lru, EINA_INLIST_GET(im));
im->cache->usage += im->cache->func.mem_size_get(im); im->cache->usage += im->cache->func.mem_size_get(im);
} }
@ -133,13 +129,9 @@ _evas_cache_image_lru_del(Image_Entry *im)
im->flags.lru = 0; im->flags.lru = 0;
im->flags.cached = 0; im->flags.cached = 0;
if (im->flags.given_mmap) 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 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->lru = eina_inlist_remove(im->cache->lru, EINA_INLIST_GET(im));
im->cache->usage -= im->cache->func.mem_size_get(im); im->cache->usage -= im->cache->func.mem_size_get(im);
} }
@ -171,6 +163,8 @@ _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
Image_Entry_Task *task; Image_Entry_Task *task;
if (!ie) return; if (!ie) return;
//// SLKL(ie->lock);
//// SLKU(ie->lock);
if ((cache) && (cache->func.debug)) cache->func.debug("deleting", ie); if ((cache) && (cache->func.debug)) cache->func.debug("deleting", ie);
if (ie->flags.delete_me == 1) return; if (ie->flags.delete_me == 1) return;
if (ie->preload) if (ie->preload)
@ -328,8 +322,12 @@ static Eina_Bool
evas_cache_image_cancelled(void *data) evas_cache_image_cancelled(void *data)
{ {
Image_Entry *current = 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 static void
@ -402,6 +400,7 @@ _evas_cache_image_async_end(void *data)
Image_Entry_Task *task; Image_Entry_Task *task;
Evas_Cache_Target *tmp; Evas_Cache_Target *tmp;
evas_cache_image_ref(ie);
ie->cache->preload = eina_list_remove(ie->cache->preload, ie); ie->cache->preload = eina_list_remove(ie->cache->preload, ie);
ie->cache->pending = eina_list_remove(ie->cache->pending, ie); ie->cache->pending = eina_list_remove(ie->cache->pending, ie);
ie->preload = NULL; ie->preload = NULL;
@ -410,7 +409,6 @@ _evas_cache_image_async_end(void *data)
ie->flags.preload_pending = 0; ie->flags.preload_pending = 0;
evas_cache_image_ref(ie);
while ((tmp = ie->targets)) while ((tmp = ie->targets))
{ {
ie->targets = (Evas_Cache_Target *) ie->targets = (Evas_Cache_Target *)
@ -441,6 +439,7 @@ _evas_cache_image_async_cancel(void *data)
Evas_Cache_Image *cache = NULL; Evas_Cache_Image *cache = NULL;
Image_Entry *ie = (Image_Entry *)data; Image_Entry *ie = (Image_Entry *)data;
evas_cache_image_ref(ie);
ie->preload = NULL; ie->preload = NULL;
ie->cache->pending = eina_list_remove(ie->cache->pending, ie); ie->cache->pending = eina_list_remove(ie->cache->pending, ie);
@ -449,7 +448,10 @@ _evas_cache_image_async_cancel(void *data)
if ((ie->flags.delete_me) || (ie->flags.dirty)) if ((ie->flags.delete_me) || (ie->flags.dirty))
{ {
ie->flags.delete_me = 0; ie->flags.delete_me = 0;
evas_cache_image_drop(ie);
SLKL(engine_lock);
_evas_cache_image_entry_delete(ie->cache, ie); _evas_cache_image_entry_delete(ie->cache, ie);
SLKU(engine_lock);
return; return;
} }
SLKL(ie->lock_task); SLKL(ie->lock_task);
@ -466,10 +468,13 @@ _evas_cache_image_async_cancel(void *data)
SLKU(ie->lock_task); SLKU(ie->lock_task);
if (ie->references == 0) if (ie->references == 0)
{ {
SLKL(engine_lock);
_evas_cache_image_lru_add(ie); _evas_cache_image_lru_add(ie);
SLKU(engine_lock);
cache = ie->cache; cache = ie->cache;
} }
if (ie->flags.loaded) _evas_cache_image_async_end(ie); if (ie->flags.loaded) _evas_cache_image_async_end(ie);
evas_cache_image_drop(ie);
if (cache) evas_cache_image_flush(cache); if (cache) evas_cache_image_flush(cache);
} }
@ -482,7 +487,12 @@ _evas_cache_image_entry_preload_add(Image_Entry *ie, const Eo *target,
Evas_Cache_Target *tg; Evas_Cache_Target *tg;
Image_Entry_Task *task; 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)); tg = calloc(1, sizeof(Evas_Cache_Target));
if (!tg) return 0; if (!tg) return 0;
@ -521,6 +531,7 @@ _evas_cache_image_entry_preload_add(Image_Entry *ie, const Eo *target,
_evas_cache_image_async_cancel, _evas_cache_image_async_cancel,
ie); ie);
} }
evas_cache_image_drop(ie);
return 1; return 1;
} }
@ -531,6 +542,7 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const Eo *target)
Eina_List *l; Eina_List *l;
Image_Entry_Task *task; Image_Entry_Task *task;
// evas_cache_image_ref(ie);
if (target) if (target)
{ {
SLKL(ie->lock_task); SLKL(ie->lock_task);
@ -579,6 +591,7 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const Eo *target)
ie->flags.pending = 1; ie->flags.pending = 1;
evas_preload_thread_cancel(ie->preload); evas_preload_thread_cancel(ie->preload);
} }
// evas_cache_image_drop(ie);
} }
EAPI int EAPI int
@ -653,6 +666,7 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
} }
evas_async_events_process(); evas_async_events_process();
SLKL(engine_lock);
EINA_INLIST_FREE(cache->lru, im) EINA_INLIST_FREE(cache->lru, im)
_evas_cache_image_entry_delete(cache, im); _evas_cache_image_entry_delete(cache, im);
EINA_INLIST_FREE(cache->lru_nodata, im) EINA_INLIST_FREE(cache->lru_nodata, im)
@ -665,6 +679,7 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
_evas_cache_image_entry_delete(cache, im); _evas_cache_image_entry_delete(cache, im);
} }
delete_list = NULL; delete_list = NULL;
eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list); 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); eina_hash_foreach(cache->mmap_activ, _evas_cache_image_free_cb, &delete_list);
while (delete_list) while (delete_list)
@ -672,6 +687,7 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
_evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list)); _evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list));
delete_list = eina_list_remove_list(delete_list, delete_list); delete_list = eina_list_remove_list(delete_list, delete_list);
} }
SLKU(engine_lock);
/* Now wait for all pending image to die */ /* Now wait for all pending image to die */
while (cache->pending) while (cache->pending)
@ -822,6 +838,7 @@ evas_cache_image_mmap_request(Evas_Cache_Image *cache,
/* find image by key in active mmap hash */ /* find image by key in active mmap hash */
SLKL(engine_lock);
im = eina_hash_find(cache->mmap_activ, hkey); im = eina_hash_find(cache->mmap_activ, hkey);
if ((im) && (!im->load_failed)) goto on_ok; if ((im) && (!im->load_failed)) goto on_ok;
else if ((im) && (im->load_failed)) else if ((im) && (im->load_failed))
@ -848,11 +865,18 @@ evas_cache_image_mmap_request(Evas_Cache_Image *cache,
} }
im = _evas_cache_image_entry_new(cache, hkey, NULL, f, NULL, key, lo, error); 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: on_ok:
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
//// SLKL(im->lock);
im->references++; im->references++;
//// SLKU(im->lock);
SLKU(engine_lock);
return im; return im;
} }
@ -896,6 +920,7 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file,
tlo.skip_head = skip; tlo.skip_head = skip;
/* find image by key in active hash */ /* find image by key in active hash */
SLKL(engine_lock);
im = eina_hash_find(cache->activ, hkey); im = eina_hash_find(cache->activ, hkey);
if ((im) && (!im->load_failed)) if ((im) && (!im->load_failed))
{ {
@ -990,7 +1015,10 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file,
on_ok: on_ok:
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
//// SLKL(im->lock);
im->references++; im->references++;
//// SLKU(im->lock);
SLKU(engine_lock);
return im; return im;
on_stat_error: on_stat_error:
@ -1012,13 +1040,18 @@ on_stat_error:
else else
*error = EVAS_LOAD_ERROR_GENERIC; *error = EVAS_LOAD_ERROR_GENERIC;
SLKU(engine_lock);
return NULL; return NULL;
} }
EAPI void EAPI void
evas_cache_image_ref(Image_Entry *im) evas_cache_image_ref(Image_Entry *im)
{ {
SLKL(engine_lock);
//// SLKL(im->lock);
im->references++; im->references++;
//// SLKU(im->lock);
SLKU(engine_lock);
} }
EAPI void EAPI void
@ -1027,9 +1060,13 @@ evas_cache_image_drop(Image_Entry *im)
Evas_Cache_Image *cache; Evas_Cache_Image *cache;
int references; int references;
SLKL(engine_lock);
//// SLKL(im->lock);
im->references--; im->references--;
if (im->references < 0) im->references = 0; if (im->references < 0) im->references = 0;
references = im->references; references = im->references;
//// SLKU(im->lock);
SLKU(engine_lock);
cache = im->cache; cache = im->cache;
@ -1042,12 +1079,16 @@ evas_cache_image_drop(Image_Entry *im)
} }
if ((im->flags.dirty) || (im->load_failed)) if ((im->flags.dirty) || (im->load_failed))
{ {
SLKL(engine_lock);
_evas_cache_image_entry_delete(cache, im); _evas_cache_image_entry_delete(cache, im);
SLKU(engine_lock);
return; return;
} }
if (cache) if (cache)
{ {
SLKL(engine_lock);
_evas_cache_image_lru_add(im); _evas_cache_image_lru_add(im);
SLKU(engine_lock);
evas_cache_image_flush(cache); evas_cache_image_flush(cache);
} }
} }
@ -1061,7 +1102,9 @@ evas_cache_image_data_not_needed(Image_Entry *im)
references = im->references; references = im->references;
if (references > 1) return; if (references > 1) return;
if ((im->flags.dirty) || (!im->flags.need_data)) return; if ((im->flags.dirty) || (!im->flags.need_data)) return;
SLKL(engine_lock);
_evas_cache_image_lru_nodata_add(im); _evas_cache_image_lru_nodata_add(im);
SLKU(engine_lock);
} }
EAPI Image_Entry * EAPI Image_Entry *
@ -1087,7 +1130,9 @@ evas_cache_image_dirty(Image_Entry *im, unsigned int x, unsigned int y, unsigned
im_dirty->references = 1; im_dirty->references = 1;
evas_cache_image_drop(im); evas_cache_image_drop(im);
} }
SLKL(engine_lock);
_evas_cache_image_dirty_add(im_dirty); _evas_cache_image_dirty_add(im_dirty);
SLKU(engine_lock);
} }
if (cache->func.debug) cache->func.debug("dirty-region", im_dirty); if (cache->func.debug) cache->func.debug("dirty-region", im_dirty);
@ -1112,7 +1157,9 @@ evas_cache_image_alone(Image_Entry *im)
if (references <= 1) if (references <= 1)
{ {
SLKL(engine_lock);
if (!im->flags.dirty) _evas_cache_image_dirty_add(im); if (!im->flags.dirty) _evas_cache_image_dirty_add(im);
SLKU(engine_lock);
} }
else else
{ {
@ -1148,14 +1195,18 @@ evas_cache_image_copied_data(Evas_Cache_Image *cache,
(cspace == EVAS_COLORSPACE_YCBCR422601_PL)) (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
w &= ~0x1; w &= ~0x1;
SLKL(engine_lock);
im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err); im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err);
SLKU(engine_lock);
if (!im) return NULL; if (!im) return NULL;
im->space = cspace; im->space = cspace;
im->flags.alpha = alpha; im->flags.alpha = alpha;
_evas_cache_image_entry_surface_alloc(cache, im, w, h); _evas_cache_image_entry_surface_alloc(cache, im, w, h);
if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0) if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0)
{ {
SLKL(engine_lock);
_evas_cache_image_entry_delete(cache, im); _evas_cache_image_entry_delete(cache, im);
SLKU(engine_lock);
return NULL; return NULL;
} }
im->references = 1; im->references = 1;
@ -1176,14 +1227,18 @@ evas_cache_image_data(Evas_Cache_Image *cache, unsigned int w, unsigned int h,
(cspace == EVAS_COLORSPACE_YCBCR422601_PL)) (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
w &= ~0x1; w &= ~0x1;
SLKL(engine_lock);
im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err); im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err);
SLKU(engine_lock);
if (!im) return NULL; if (!im) return NULL;
im->w = w; im->w = w;
im->h = h; im->h = h;
im->flags.alpha = alpha; im->flags.alpha = alpha;
if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0) if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0)
{ {
SLKL(engine_lock);
_evas_cache_image_entry_delete(cache, im); _evas_cache_image_entry_delete(cache, im);
SLKU(engine_lock);
return NULL; return NULL;
} }
im->references = 1; im->references = 1;
@ -1213,14 +1268,21 @@ evas_cache_image_size_set(Image_Entry *im, unsigned int w, unsigned int h)
Image_Entry *im2 = NULL; Image_Entry *im2 = NULL;
int error; int error;
evas_cache_image_ref(im);
if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) || if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
(im->space == EVAS_COLORSPACE_YCBCR422P709_PL) || (im->space == EVAS_COLORSPACE_YCBCR422P709_PL) ||
(im->space == EVAS_COLORSPACE_YCBCR422601_PL)) (im->space == EVAS_COLORSPACE_YCBCR422601_PL))
w &= ~0x1; 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; cache = im->cache;
SLKL(engine_lock);
im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &error); im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &error);
SLKU(engine_lock);
if (!im2) goto on_error; if (!im2) goto on_error;
im2->flags.alpha = im->flags.alpha; im2->flags.alpha = im->flags.alpha;
@ -1233,10 +1295,14 @@ evas_cache_image_size_set(Image_Entry *im, unsigned int w, unsigned int h)
im2->flags.loaded = EINA_TRUE; im2->flags.loaded = EINA_TRUE;
evas_cache_image_drop(im); evas_cache_image_drop(im);
if (cache->func.debug) cache->func.debug("size_set", im2); if (cache->func.debug) cache->func.debug("size_set", im2);
evas_cache_image_drop(im);
return im2; return im2;
on_error: on_error:
SLKL(engine_lock);
if (im2) _evas_cache_image_entry_delete(cache, im2); if (im2) _evas_cache_image_entry_delete(cache, im2);
SLKU(engine_lock);
evas_cache_image_drop(im);
evas_cache_image_drop(im); evas_cache_image_drop(im);
return NULL; return NULL;
} }
@ -1247,7 +1313,12 @@ evas_cache_image_load_data(Image_Entry *im)
Eina_Bool preload = EINA_FALSE; Eina_Bool preload = EINA_FALSE;
int error = EVAS_LOAD_ERROR_NONE; 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); evas_common_rgba_pending_unloads_remove(im);
if (im->preload) if (im->preload)
{ {
@ -1269,7 +1340,11 @@ evas_cache_image_load_data(Image_Entry *im)
} }
} }
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); SLKL(im->lock);
im->flags.in_progress = EINA_TRUE; im->flags.in_progress = EINA_TRUE;
@ -1285,20 +1360,27 @@ evas_cache_image_load_data(Image_Entry *im)
im->flags.loaded = 0; im->flags.loaded = 0;
} }
if (preload) _evas_cache_image_async_end(im); if (preload) _evas_cache_image_async_end(im);
evas_cache_image_drop(im);
return error; return error;
} }
EAPI void EAPI void
evas_cache_image_unload_data(Image_Entry *im) 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); evas_cache_image_preload_cancel(im, NULL);
if (SLKT(im->lock) == EINA_FALSE) /* can't get image lock - busy async load */ if (SLKT(im->lock) == EINA_FALSE) /* can't get image lock - busy async load */
{ {
SLKL(im->lock_cancel); SLKL(im->lock_cancel);
im->flags.unload_cancel = EINA_TRUE; im->flags.unload_cancel = EINA_TRUE;
SLKU(im->lock_cancel); SLKU(im->lock_cancel);
evas_cache_image_drop(im);
return; return;
} }
@ -1308,11 +1390,13 @@ evas_cache_image_unload_data(Image_Entry *im)
{ {
SLKU(im->lock_cancel); SLKU(im->lock_cancel);
SLKU(im->lock); SLKU(im->lock);
evas_cache_image_drop(im);
return; return;
} }
SLKU(im->lock_cancel); SLKU(im->lock_cancel);
im->cache->func.destructor(im); im->cache->func.destructor(im);
SLKU(im->lock); SLKU(im->lock);
evas_cache_image_drop(im);
//FIXME: imagedataunload - inform owners //FIXME: imagedataunload - inform owners
} }
@ -1328,10 +1412,14 @@ evas_cache_image_unload_all(Evas_Cache_Image *cache)
{ {
Image_Entry *im; 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, im) evas_cache_image_unload_data(im);
EINA_INLIST_FOREACH(cache->lru_nodata, 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->activ, _evas_cache_image_unload_cb, NULL);
eina_hash_foreach(cache->inactiv, _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; static int async_frozen = 0;
@ -1367,6 +1455,7 @@ evas_cache_image_preload_data(Image_Entry *im, const Eo *target,
{ {
RGBA_Image *img = (RGBA_Image *)im; RGBA_Image *img = (RGBA_Image *)im;
evas_cache_image_ref(im);
if (((int)im->w > 0) && ((int)im->h > 0) && if (((int)im->w > 0) && ((int)im->h > 0) &&
(((im->flags.loaded) && (img->image.data)) || (((im->flags.loaded) && (img->image.data)) ||
(im->flags.textured && !im->flags.updated_data))) (im->flags.textured && !im->flags.updated_data)))
@ -1388,18 +1477,22 @@ evas_cache_image_preload_data(Image_Entry *im, const Eo *target,
free(tmp); free(tmp);
} }
evas_object_inform_call_image_preloaded((Evas_Object*)target); evas_object_inform_call_image_preloaded((Evas_Object*)target);
evas_cache_image_drop(im);
return; return;
} }
im->flags.loaded = 0; im->flags.loaded = 0;
if (!_evas_cache_image_entry_preload_add(im, target, func, engine_data, custom_data)) if (!_evas_cache_image_entry_preload_add(im, target, func, engine_data, custom_data))
evas_object_inform_call_image_preloaded((Evas_Object*) target); evas_object_inform_call_image_preloaded((Evas_Object*) target);
evas_cache_image_drop(im);
} }
EAPI void EAPI void
evas_cache_image_preload_cancel(Image_Entry *im, const Eo *target) evas_cache_image_preload_cancel(Image_Entry *im, const Eo *target)
{ {
if (!target) return; if (!target) return;
evas_cache_image_ref(im);
_evas_cache_image_entry_preload_remove(im, target); _evas_cache_image_entry_preload_remove(im, target);
evas_cache_image_drop(im);
} }
#ifdef CACHEDUMP #ifdef CACHEDUMP
@ -1436,6 +1529,7 @@ _dump_cache(Evas_Cache_Image *cache)
cache->limit / 1024); cache->limit / 1024);
printf("................................................................\n"); printf("................................................................\n");
total = 0; total = 0;
SLKL(engine_lock);
EINA_INLIST_FOREACH(cache->lru_nodata, im) EINA_INLIST_FOREACH(cache->lru_nodata, im)
_dump_img(im, "NODATA"); _dump_img(im, "NODATA");
EINA_INLIST_FOREACH(cache->lru, im) EINA_INLIST_FOREACH(cache->lru, im)
@ -1445,6 +1539,7 @@ _dump_cache(Evas_Cache_Image *cache)
total, total,
cache->usage); cache->usage);
eina_hash_foreach(cache->activ, _dump_cache_active, NULL); eina_hash_foreach(cache->activ, _dump_cache_active, NULL);
SLKU(engine_lock);
} }
#endif #endif
@ -1456,6 +1551,7 @@ evas_cache_image_flush(Evas_Cache_Image *cache)
#endif #endif
if (cache->limit == (unsigned int)-1) return -1; if (cache->limit == (unsigned int)-1) return -1;
SLKL(engine_lock);
while ((cache->lru) && (cache->limit < (unsigned int)cache->usage)) while ((cache->lru) && (cache->limit < (unsigned int)cache->usage))
{ {
Image_Entry *im; Image_Entry *im;
@ -1475,6 +1571,7 @@ evas_cache_image_flush(Evas_Cache_Image *cache)
cache->func.surface_delete(im); cache->func.surface_delete(im);
im->flags.loaded = 0; im->flags.loaded = 0;
} }
SLKU(engine_lock);
return cache->usage; return cache->usage;
} }
@ -1485,7 +1582,9 @@ evas_cache_image_empty(Evas_Cache_Image *cache)
int err; int err;
Image_Entry *im; Image_Entry *im;
SLKL(engine_lock);
im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err); im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err);
SLKU(engine_lock);
if (!im) return NULL; if (!im) return NULL;
im->references = 1; im->references = 1;
return im; return im;
@ -1494,16 +1593,23 @@ evas_cache_image_empty(Evas_Cache_Image *cache)
EAPI void EAPI void
evas_cache_image_colorspace(Image_Entry *im, Evas_Colorspace cspace) 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; im->space = cspace;
if (!im->cache) return; if (!im->cache) goto done;
im->cache->func.color_space(im, cspace); im->cache->func.color_space(im, cspace);
done:
evas_cache_image_drop(im);
} }
EAPI void * EAPI void *
evas_cache_private_from_image_entry_get(Image_Entry *im) 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 * EAPI void *