summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-03-09 11:18:32 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-03-09 11:21:19 +0900
commitd550190d6be8fe4d1ba44042ad8d9c17cf232079 (patch)
treea6d95f2034e6a6af8aa8259f9802fdc0328c10b5
parent1a5563ab636ee37bea39d68d0da04114c2ac6245 (diff)
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
-rw-r--r--src/lib/evas/cache/evas_cache_image.c156
1 files changed, 131 insertions, 25 deletions
diff --git a/src/lib/evas/cache/evas_cache_image.c b/src/lib/evas/cache/evas_cache_image.c
index a404fadb02..ff958581cf 100644
--- a/src/lib/evas/cache/evas_cache_image.c
+++ b/src/lib/evas/cache/evas_cache_image.c
@@ -109,18 +109,14 @@ _evas_cache_image_lru_add(Image_Entry *im)
109 if (im->flags.lru) return; 109 if (im->flags.lru) return;
110 _evas_cache_image_dirty_del(im); 110 _evas_cache_image_dirty_del(im);
111 _evas_cache_image_activ_del(im); 111 _evas_cache_image_activ_del(im);
112 _evas_cache_image_lru_nodata_del(im); 112 _evas_cache_image_lru_nodata_del(im);
113 if (!im->cache_key) return; 113 if (!im->cache_key) return;
114 im->flags.lru = 1; 114 im->flags.lru = 1;
115 im->flags.cached = 1; 115 im->flags.cached = 1;
116 if (im->flags.given_mmap) 116 if (im->flags.given_mmap)
117 { 117 eina_hash_direct_add(im->cache->mmap_inactiv, im->cache_key, im);
118 eina_hash_direct_add(im->cache->mmap_inactiv, im->cache_key, im);
119 }
120 else 118 else
121 { 119 eina_hash_direct_add(im->cache->inactiv, im->cache_key, im);
122 eina_hash_direct_add(im->cache->inactiv, im->cache_key, im);
123 }
124 im->cache->lru = eina_inlist_prepend(im->cache->lru, EINA_INLIST_GET(im)); 120 im->cache->lru = eina_inlist_prepend(im->cache->lru, EINA_INLIST_GET(im));
125 im->cache->usage += im->cache->func.mem_size_get(im); 121 im->cache->usage += im->cache->func.mem_size_get(im);
126} 122}
@@ -133,13 +129,9 @@ _evas_cache_image_lru_del(Image_Entry *im)
133 im->flags.lru = 0; 129 im->flags.lru = 0;
134 im->flags.cached = 0; 130 im->flags.cached = 0;
135 if (im->flags.given_mmap) 131 if (im->flags.given_mmap)
136 { 132 eina_hash_del(im->cache->mmap_inactiv, im->cache_key, im);
137 eina_hash_del(im->cache->mmap_inactiv, im->cache_key, im);
138 }
139 else 133 else
140 { 134 eina_hash_del(im->cache->inactiv, im->cache_key, im);
141 eina_hash_del(im->cache->inactiv, im->cache_key, im);
142 }
143 im->cache->lru = eina_inlist_remove(im->cache->lru, EINA_INLIST_GET(im)); 135 im->cache->lru = eina_inlist_remove(im->cache->lru, EINA_INLIST_GET(im));
144 im->cache->usage -= im->cache->func.mem_size_get(im); 136 im->cache->usage -= im->cache->func.mem_size_get(im);
145} 137}
@@ -171,6 +163,8 @@ _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
171 Image_Entry_Task *task; 163 Image_Entry_Task *task;
172 164
173 if (!ie) return; 165 if (!ie) return;
166//// SLKL(ie->lock);
167//// SLKU(ie->lock);
174 if ((cache) && (cache->func.debug)) cache->func.debug("deleting", ie); 168 if ((cache) && (cache->func.debug)) cache->func.debug("deleting", ie);
175 if (ie->flags.delete_me == 1) return; 169 if (ie->flags.delete_me == 1) return;
176 if (ie->preload) 170 if (ie->preload)
@@ -328,8 +322,12 @@ static Eina_Bool
328evas_cache_image_cancelled(void *data) 322evas_cache_image_cancelled(void *data)
329{ 323{
330 Image_Entry *current = data; 324 Image_Entry *current = data;
325 Eina_Bool ret;
331 326
332 return evas_preload_thread_cancelled_is(current->preload); 327 evas_cache_image_ref(current);
328 ret = evas_preload_thread_cancelled_is(current->preload);
329 evas_cache_image_drop(current);
330 return ret;
333} 331}
334 332
335static void 333static void
@@ -402,6 +400,7 @@ _evas_cache_image_async_end(void *data)
402 Image_Entry_Task *task; 400 Image_Entry_Task *task;
403 Evas_Cache_Target *tmp; 401 Evas_Cache_Target *tmp;
404 402
403 evas_cache_image_ref(ie);
405 ie->cache->preload = eina_list_remove(ie->cache->preload, ie); 404 ie->cache->preload = eina_list_remove(ie->cache->preload, ie);
406 ie->cache->pending = eina_list_remove(ie->cache->pending, ie); 405 ie->cache->pending = eina_list_remove(ie->cache->pending, ie);
407 ie->preload = NULL; 406 ie->preload = NULL;
@@ -410,7 +409,6 @@ _evas_cache_image_async_end(void *data)
410 409
411 ie->flags.preload_pending = 0; 410 ie->flags.preload_pending = 0;
412 411
413 evas_cache_image_ref(ie);
414 while ((tmp = ie->targets)) 412 while ((tmp = ie->targets))
415 { 413 {
416 ie->targets = (Evas_Cache_Target *) 414 ie->targets = (Evas_Cache_Target *)
@@ -441,6 +439,7 @@ _evas_cache_image_async_cancel(void *data)
441 Evas_Cache_Image *cache = NULL; 439 Evas_Cache_Image *cache = NULL;
442 Image_Entry *ie = (Image_Entry *)data; 440 Image_Entry *ie = (Image_Entry *)data;
443 441
442 evas_cache_image_ref(ie);
444 ie->preload = NULL; 443 ie->preload = NULL;
445 ie->cache->pending = eina_list_remove(ie->cache->pending, ie); 444 ie->cache->pending = eina_list_remove(ie->cache->pending, ie);
446 445
@@ -449,7 +448,10 @@ _evas_cache_image_async_cancel(void *data)
449 if ((ie->flags.delete_me) || (ie->flags.dirty)) 448 if ((ie->flags.delete_me) || (ie->flags.dirty))
450 { 449 {
451 ie->flags.delete_me = 0; 450 ie->flags.delete_me = 0;
451 evas_cache_image_drop(ie);
452 SLKL(engine_lock);
452 _evas_cache_image_entry_delete(ie->cache, ie); 453 _evas_cache_image_entry_delete(ie->cache, ie);
454 SLKU(engine_lock);
453 return; 455 return;
454 } 456 }
455 SLKL(ie->lock_task); 457 SLKL(ie->lock_task);
@@ -466,10 +468,13 @@ _evas_cache_image_async_cancel(void *data)
466 SLKU(ie->lock_task); 468 SLKU(ie->lock_task);
467 if (ie->references == 0) 469 if (ie->references == 0)
468 { 470 {
471 SLKL(engine_lock);
469 _evas_cache_image_lru_add(ie); 472 _evas_cache_image_lru_add(ie);
473 SLKU(engine_lock);
470 cache = ie->cache; 474 cache = ie->cache;
471 } 475 }
472 if (ie->flags.loaded) _evas_cache_image_async_end(ie); 476 if (ie->flags.loaded) _evas_cache_image_async_end(ie);
477 evas_cache_image_drop(ie);
473 if (cache) evas_cache_image_flush(cache); 478 if (cache) evas_cache_image_flush(cache);
474} 479}
475 480
@@ -482,7 +487,12 @@ _evas_cache_image_entry_preload_add(Image_Entry *ie, const Eo *target,
482 Evas_Cache_Target *tg; 487 Evas_Cache_Target *tg;
483 Image_Entry_Task *task; 488 Image_Entry_Task *task;
484 489
485 if (ie->flags.preload_done) return 0; 490 evas_cache_image_ref(ie);
491 if (ie->flags.preload_done)
492 {
493 evas_cache_image_drop(ie);
494 return 0;
495 }
486 496
487 tg = calloc(1, sizeof(Evas_Cache_Target)); 497 tg = calloc(1, sizeof(Evas_Cache_Target));
488 if (!tg) return 0; 498 if (!tg) return 0;
@@ -521,6 +531,7 @@ _evas_cache_image_entry_preload_add(Image_Entry *ie, const Eo *target,
521 _evas_cache_image_async_cancel, 531 _evas_cache_image_async_cancel,
522 ie); 532 ie);
523 } 533 }
534 evas_cache_image_drop(ie);
524 return 1; 535 return 1;
525} 536}
526 537
@@ -531,6 +542,7 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const Eo *target)
531 Eina_List *l; 542 Eina_List *l;
532 Image_Entry_Task *task; 543 Image_Entry_Task *task;
533 544
545// evas_cache_image_ref(ie);
534 if (target) 546 if (target)
535 { 547 {
536 SLKL(ie->lock_task); 548 SLKL(ie->lock_task);
@@ -579,6 +591,7 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const Eo *target)
579 ie->flags.pending = 1; 591 ie->flags.pending = 1;
580 evas_preload_thread_cancel(ie->preload); 592 evas_preload_thread_cancel(ie->preload);
581 } 593 }
594// evas_cache_image_drop(ie);
582} 595}
583 596
584EAPI int 597EAPI int
@@ -653,6 +666,7 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
653 } 666 }
654 evas_async_events_process(); 667 evas_async_events_process();
655 668
669 SLKL(engine_lock);
656 EINA_INLIST_FREE(cache->lru, im) 670 EINA_INLIST_FREE(cache->lru, im)
657 _evas_cache_image_entry_delete(cache, im); 671 _evas_cache_image_entry_delete(cache, im);
658 EINA_INLIST_FREE(cache->lru_nodata, im) 672 EINA_INLIST_FREE(cache->lru_nodata, im)
@@ -665,6 +679,7 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
665 _evas_cache_image_entry_delete(cache, im); 679 _evas_cache_image_entry_delete(cache, im);
666 } 680 }
667 delete_list = NULL; 681 delete_list = NULL;
682
668 eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list); 683 eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list);
669 eina_hash_foreach(cache->mmap_activ, _evas_cache_image_free_cb, &delete_list); 684 eina_hash_foreach(cache->mmap_activ, _evas_cache_image_free_cb, &delete_list);
670 while (delete_list) 685 while (delete_list)
@@ -672,6 +687,7 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
672 _evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list)); 687 _evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list));
673 delete_list = eina_list_remove_list(delete_list, delete_list); 688 delete_list = eina_list_remove_list(delete_list, delete_list);
674 } 689 }
690 SLKU(engine_lock);
675 691
676 /* Now wait for all pending image to die */ 692 /* Now wait for all pending image to die */
677 while (cache->pending) 693 while (cache->pending)
@@ -822,6 +838,7 @@ evas_cache_image_mmap_request(Evas_Cache_Image *cache,
822 838
823 839
824 /* find image by key in active mmap hash */ 840 /* find image by key in active mmap hash */
841 SLKL(engine_lock);
825 im = eina_hash_find(cache->mmap_activ, hkey); 842 im = eina_hash_find(cache->mmap_activ, hkey);
826 if ((im) && (!im->load_failed)) goto on_ok; 843 if ((im) && (!im->load_failed)) goto on_ok;
827 else if ((im) && (im->load_failed)) 844 else if ((im) && (im->load_failed))
@@ -848,11 +865,18 @@ evas_cache_image_mmap_request(Evas_Cache_Image *cache,
848 } 865 }
849 866
850 im = _evas_cache_image_entry_new(cache, hkey, NULL, f, NULL, key, lo, error); 867 im = _evas_cache_image_entry_new(cache, hkey, NULL, f, NULL, key, lo, error);
851 if (!im) return NULL; 868 if (!im)
869 {
870 SLKU(engine_lock);
871 return NULL;
872 }
852 873
853 on_ok: 874 on_ok:
854 *error = EVAS_LOAD_ERROR_NONE; 875 *error = EVAS_LOAD_ERROR_NONE;
876//// SLKL(im->lock);
855 im->references++; 877 im->references++;
878//// SLKU(im->lock);
879 SLKU(engine_lock);
856 return im; 880 return im;
857} 881}
858 882
@@ -896,6 +920,7 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file,
896 tlo.skip_head = skip; 920 tlo.skip_head = skip;
897 921
898 /* find image by key in active hash */ 922 /* find image by key in active hash */
923 SLKL(engine_lock);
899 im = eina_hash_find(cache->activ, hkey); 924 im = eina_hash_find(cache->activ, hkey);
900 if ((im) && (!im->load_failed)) 925 if ((im) && (!im->load_failed))
901 { 926 {
@@ -990,7 +1015,10 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file,
990 1015
991on_ok: 1016on_ok:
992 *error = EVAS_LOAD_ERROR_NONE; 1017 *error = EVAS_LOAD_ERROR_NONE;
1018//// SLKL(im->lock);
993 im->references++; 1019 im->references++;
1020//// SLKU(im->lock);
1021 SLKU(engine_lock);
994 return im; 1022 return im;
995 1023
996on_stat_error: 1024on_stat_error:
@@ -1012,13 +1040,18 @@ on_stat_error:
1012 else 1040 else
1013 *error = EVAS_LOAD_ERROR_GENERIC; 1041 *error = EVAS_LOAD_ERROR_GENERIC;
1014 1042
1043 SLKU(engine_lock);
1015 return NULL; 1044 return NULL;
1016} 1045}
1017 1046
1018EAPI void 1047EAPI void
1019evas_cache_image_ref(Image_Entry *im) 1048evas_cache_image_ref(Image_Entry *im)
1020{ 1049{
1050 SLKL(engine_lock);
1051//// SLKL(im->lock);
1021 im->references++; 1052 im->references++;
1053//// SLKU(im->lock);
1054 SLKU(engine_lock);
1022} 1055}
1023 1056
1024EAPI void 1057EAPI void
@@ -1027,9 +1060,13 @@ evas_cache_image_drop(Image_Entry *im)
1027 Evas_Cache_Image *cache; 1060 Evas_Cache_Image *cache;
1028 int references; 1061 int references;
1029 1062
1063 SLKL(engine_lock);
1064//// SLKL(im->lock);
1030 im->references--; 1065 im->references--;
1031 if (im->references < 0) im->references = 0; 1066 if (im->references < 0) im->references = 0;
1032 references = im->references; 1067 references = im->references;
1068//// SLKU(im->lock);
1069 SLKU(engine_lock);
1033 1070
1034 cache = im->cache; 1071 cache = im->cache;
1035 1072
@@ -1042,12 +1079,16 @@ evas_cache_image_drop(Image_Entry *im)
1042 } 1079 }
1043 if ((im->flags.dirty) || (im->load_failed)) 1080 if ((im->flags.dirty) || (im->load_failed))
1044 { 1081 {
1082 SLKL(engine_lock);
1045 _evas_cache_image_entry_delete(cache, im); 1083 _evas_cache_image_entry_delete(cache, im);
1084 SLKU(engine_lock);
1046 return; 1085 return;
1047 } 1086 }
1048 if (cache) 1087 if (cache)
1049 { 1088 {
1089 SLKL(engine_lock);
1050 _evas_cache_image_lru_add(im); 1090 _evas_cache_image_lru_add(im);
1091 SLKU(engine_lock);
1051 evas_cache_image_flush(cache); 1092 evas_cache_image_flush(cache);
1052 } 1093 }
1053 } 1094 }
@@ -1061,7 +1102,9 @@ evas_cache_image_data_not_needed(Image_Entry *im)
1061 references = im->references; 1102 references = im->references;
1062 if (references > 1) return; 1103 if (references > 1) return;
1063 if ((im->flags.dirty) || (!im->flags.need_data)) return; 1104 if ((im->flags.dirty) || (!im->flags.need_data)) return;
1105 SLKL(engine_lock);
1064 _evas_cache_image_lru_nodata_add(im); 1106 _evas_cache_image_lru_nodata_add(im);
1107 SLKU(engine_lock);
1065} 1108}
1066 1109
1067EAPI Image_Entry * 1110EAPI Image_Entry *
@@ -1087,7 +1130,9 @@ evas_cache_image_dirty(Image_Entry *im, unsigned int x, unsigned int y, unsigned
1087 im_dirty->references = 1; 1130 im_dirty->references = 1;
1088 evas_cache_image_drop(im); 1131 evas_cache_image_drop(im);
1089 } 1132 }
1133 SLKL(engine_lock);
1090 _evas_cache_image_dirty_add(im_dirty); 1134 _evas_cache_image_dirty_add(im_dirty);
1135 SLKU(engine_lock);
1091 } 1136 }
1092 1137
1093 if (cache->func.debug) cache->func.debug("dirty-region", im_dirty); 1138 if (cache->func.debug) cache->func.debug("dirty-region", im_dirty);
@@ -1112,7 +1157,9 @@ evas_cache_image_alone(Image_Entry *im)
1112 1157
1113 if (references <= 1) 1158 if (references <= 1)
1114 { 1159 {
1160 SLKL(engine_lock);
1115 if (!im->flags.dirty) _evas_cache_image_dirty_add(im); 1161 if (!im->flags.dirty) _evas_cache_image_dirty_add(im);
1162 SLKU(engine_lock);
1116 } 1163 }
1117 else 1164 else
1118 { 1165 {
@@ -1148,14 +1195,18 @@ evas_cache_image_copied_data(Evas_Cache_Image *cache,
1148 (cspace == EVAS_COLORSPACE_YCBCR422601_PL)) 1195 (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
1149 w &= ~0x1; 1196 w &= ~0x1;
1150 1197
1198 SLKL(engine_lock);
1151 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err); 1199 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err);
1200 SLKU(engine_lock);
1152 if (!im) return NULL; 1201 if (!im) return NULL;
1153 im->space = cspace; 1202 im->space = cspace;
1154 im->flags.alpha = alpha; 1203 im->flags.alpha = alpha;
1155 _evas_cache_image_entry_surface_alloc(cache, im, w, h); 1204 _evas_cache_image_entry_surface_alloc(cache, im, w, h);
1156 if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0) 1205 if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0)
1157 { 1206 {
1207 SLKL(engine_lock);
1158 _evas_cache_image_entry_delete(cache, im); 1208 _evas_cache_image_entry_delete(cache, im);
1209 SLKU(engine_lock);
1159 return NULL; 1210 return NULL;
1160 } 1211 }
1161 im->references = 1; 1212 im->references = 1;
@@ -1176,14 +1227,18 @@ evas_cache_image_data(Evas_Cache_Image *cache, unsigned int w, unsigned int h,
1176 (cspace == EVAS_COLORSPACE_YCBCR422601_PL)) 1227 (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
1177 w &= ~0x1; 1228 w &= ~0x1;
1178 1229
1230 SLKL(engine_lock);
1179 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err); 1231 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err);
1232 SLKU(engine_lock);
1180 if (!im) return NULL; 1233 if (!im) return NULL;
1181 im->w = w; 1234 im->w = w;
1182 im->h = h; 1235 im->h = h;
1183 im->flags.alpha = alpha; 1236 im->flags.alpha = alpha;
1184 if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0) 1237 if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0)
1185 { 1238 {
1239 SLKL(engine_lock);
1186 _evas_cache_image_entry_delete(cache, im); 1240 _evas_cache_image_entry_delete(cache, im);
1241 SLKU(engine_lock);
1187 return NULL; 1242 return NULL;
1188 } 1243 }
1189 im->references = 1; 1244 im->references = 1;
@@ -1213,14 +1268,21 @@ evas_cache_image_size_set(Image_Entry *im, unsigned int w, unsigned int h)
1213 Image_Entry *im2 = NULL; 1268 Image_Entry *im2 = NULL;
1214 int error; 1269 int error;
1215 1270
1271 evas_cache_image_ref(im);
1216 if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) || 1272 if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
1217 (im->space == EVAS_COLORSPACE_YCBCR422P709_PL) || 1273 (im->space == EVAS_COLORSPACE_YCBCR422P709_PL) ||
1218 (im->space == EVAS_COLORSPACE_YCBCR422601_PL)) 1274 (im->space == EVAS_COLORSPACE_YCBCR422601_PL))
1219 w &= ~0x1; 1275 w &= ~0x1;
1220 if ((im->w == w) && (im->h == h)) return im; 1276 if ((im->w == w) && (im->h == h))
1277 {
1278 evas_cache_image_drop(im);
1279 return im;
1280 }
1221 1281
1222 cache = im->cache; 1282 cache = im->cache;
1283 SLKL(engine_lock);
1223 im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &error); 1284 im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &error);
1285 SLKU(engine_lock);
1224 if (!im2) goto on_error; 1286 if (!im2) goto on_error;
1225 1287
1226 im2->flags.alpha = im->flags.alpha; 1288 im2->flags.alpha = im->flags.alpha;
@@ -1233,10 +1295,14 @@ evas_cache_image_size_set(Image_Entry *im, unsigned int w, unsigned int h)
1233 im2->flags.loaded = EINA_TRUE; 1295 im2->flags.loaded = EINA_TRUE;
1234 evas_cache_image_drop(im); 1296 evas_cache_image_drop(im);
1235 if (cache->func.debug) cache->func.debug("size_set", im2); 1297 if (cache->func.debug) cache->func.debug("size_set", im2);
1298 evas_cache_image_drop(im);
1236 return im2; 1299 return im2;
1237 1300
1238on_error: 1301on_error:
1302 SLKL(engine_lock);
1239 if (im2) _evas_cache_image_entry_delete(cache, im2); 1303 if (im2) _evas_cache_image_entry_delete(cache, im2);
1304 SLKU(engine_lock);
1305 evas_cache_image_drop(im);
1240 evas_cache_image_drop(im); 1306 evas_cache_image_drop(im);
1241 return NULL; 1307 return NULL;
1242} 1308}
@@ -1247,7 +1313,12 @@ evas_cache_image_load_data(Image_Entry *im)
1247 Eina_Bool preload = EINA_FALSE; 1313 Eina_Bool preload = EINA_FALSE;
1248 int error = EVAS_LOAD_ERROR_NONE; 1314 int error = EVAS_LOAD_ERROR_NONE;
1249 1315
1250 if ((im->flags.loaded) && (!im->animated.animated)) return error; 1316 evas_cache_image_ref(im);
1317 if ((im->flags.loaded) && (!im->animated.animated))
1318 {
1319 evas_cache_image_drop(im);
1320 return error;
1321 }
1251 evas_common_rgba_pending_unloads_remove(im); 1322 evas_common_rgba_pending_unloads_remove(im);
1252 if (im->preload) 1323 if (im->preload)
1253 { 1324 {
@@ -1269,7 +1340,11 @@ evas_cache_image_load_data(Image_Entry *im)
1269 } 1340 }
1270 } 1341 }
1271 1342
1272 if ((im->flags.loaded) && (!im->animated.animated)) return error; 1343 if ((im->flags.loaded) && (!im->animated.animated))
1344 {
1345 evas_cache_image_drop(im);
1346 return error;
1347 }
1273 1348
1274 SLKL(im->lock); 1349 SLKL(im->lock);
1275 im->flags.in_progress = EINA_TRUE; 1350 im->flags.in_progress = EINA_TRUE;
@@ -1285,20 +1360,27 @@ evas_cache_image_load_data(Image_Entry *im)
1285 im->flags.loaded = 0; 1360 im->flags.loaded = 0;
1286 } 1361 }
1287 if (preload) _evas_cache_image_async_end(im); 1362 if (preload) _evas_cache_image_async_end(im);
1363 evas_cache_image_drop(im);
1288 return error; 1364 return error;
1289} 1365}
1290 1366
1291EAPI void 1367EAPI void
1292evas_cache_image_unload_data(Image_Entry *im) 1368evas_cache_image_unload_data(Image_Entry *im)
1293{ 1369{
1294 if (im->flags.in_progress) return; 1370 evas_cache_image_ref(im);
1371 if (im->flags.in_progress)
1372 {
1373 evas_cache_image_drop(im);
1374 return;
1375 }
1295 evas_cache_image_preload_cancel(im, NULL); 1376 evas_cache_image_preload_cancel(im, NULL);
1296 1377
1297 if (SLKT(im->lock) == EINA_FALSE) /* can't get image lock - busy async load */ 1378 if (SLKT(im->lock) == EINA_FALSE) /* can't get image lock - busy async load */
1298 { 1379 {
1299 SLKL(im->lock_cancel); 1380 SLKL(im->lock_cancel);
1300 im->flags.unload_cancel = EINA_TRUE; 1381 im->flags.unload_cancel = EINA_TRUE;
1301 SLKU(im->lock_cancel); 1382 SLKU(im->lock_cancel);
1383 evas_cache_image_drop(im);
1302 return; 1384 return;
1303 } 1385 }
1304 1386
@@ -1308,11 +1390,13 @@ evas_cache_image_unload_data(Image_Entry *im)
1308 { 1390 {
1309 SLKU(im->lock_cancel); 1391 SLKU(im->lock_cancel);
1310 SLKU(im->lock); 1392 SLKU(im->lock);
1393 evas_cache_image_drop(im);
1311 return; 1394 return;
1312 } 1395 }
1313 SLKU(im->lock_cancel); 1396 SLKU(im->lock_cancel);
1314 im->cache->func.destructor(im); 1397 im->cache->func.destructor(im);
1315 SLKU(im->lock); 1398 SLKU(im->lock);
1399 evas_cache_image_drop(im);
1316 //FIXME: imagedataunload - inform owners 1400 //FIXME: imagedataunload - inform owners
1317} 1401}
1318 1402
@@ -1328,10 +1412,14 @@ evas_cache_image_unload_all(Evas_Cache_Image *cache)
1328{ 1412{
1329 Image_Entry *im; 1413 Image_Entry *im;
1330 1414
1415// _evas_cache_image_unload_cb -> evas_cache_image_unload_data -> evas_cache_image_ref
1416// deadlock
1417////// SLKL(engine_lock);
1331 EINA_INLIST_FOREACH(cache->lru, im) evas_cache_image_unload_data(im); 1418 EINA_INLIST_FOREACH(cache->lru, im) evas_cache_image_unload_data(im);
1332 EINA_INLIST_FOREACH(cache->lru_nodata, im) evas_cache_image_unload_data(im); 1419 EINA_INLIST_FOREACH(cache->lru_nodata, im) evas_cache_image_unload_data(im);
1333 eina_hash_foreach(cache->activ, _evas_cache_image_unload_cb, NULL); 1420 eina_hash_foreach(cache->activ, _evas_cache_image_unload_cb, NULL);
1334 eina_hash_foreach(cache->inactiv, _evas_cache_image_unload_cb, NULL); 1421 eina_hash_foreach(cache->inactiv, _evas_cache_image_unload_cb, NULL);
1422////// SLKU(engine_lock);
1335} 1423}
1336 1424
1337static int async_frozen = 0; 1425static int async_frozen = 0;
@@ -1367,6 +1455,7 @@ evas_cache_image_preload_data(Image_Entry *im, const Eo *target,
1367{ 1455{
1368 RGBA_Image *img = (RGBA_Image *)im; 1456 RGBA_Image *img = (RGBA_Image *)im;
1369 1457
1458 evas_cache_image_ref(im);
1370 if (((int)im->w > 0) && ((int)im->h > 0) && 1459 if (((int)im->w > 0) && ((int)im->h > 0) &&
1371 (((im->flags.loaded) && (img->image.data)) || 1460 (((im->flags.loaded) && (img->image.data)) ||
1372 (im->flags.textured && !im->flags.updated_data))) 1461 (im->flags.textured && !im->flags.updated_data)))
@@ -1388,18 +1477,22 @@ evas_cache_image_preload_data(Image_Entry *im, const Eo *target,
1388 free(tmp); 1477 free(tmp);
1389 } 1478 }
1390 evas_object_inform_call_image_preloaded((Evas_Object*)target); 1479 evas_object_inform_call_image_preloaded((Evas_Object*)target);
1480 evas_cache_image_drop(im);
1391 return; 1481 return;
1392 } 1482 }
1393 im->flags.loaded = 0; 1483 im->flags.loaded = 0;
1394 if (!_evas_cache_image_entry_preload_add(im, target, func, engine_data, custom_data)) 1484 if (!_evas_cache_image_entry_preload_add(im, target, func, engine_data, custom_data))
1395 evas_object_inform_call_image_preloaded((Evas_Object*) target); 1485 evas_object_inform_call_image_preloaded((Evas_Object*) target);
1486 evas_cache_image_drop(im);
1396} 1487}
1397 1488
1398EAPI void 1489EAPI void
1399evas_cache_image_preload_cancel(Image_Entry *im, const Eo *target) 1490evas_cache_image_preload_cancel(Image_Entry *im, const Eo *target)
1400{ 1491{
1401 if (!target) return; 1492 if (!target) return;
1493 evas_cache_image_ref(im);
1402 _evas_cache_image_entry_preload_remove(im, target); 1494 _evas_cache_image_entry_preload_remove(im, target);
1495 evas_cache_image_drop(im);
1403} 1496}
1404 1497
1405#ifdef CACHEDUMP 1498#ifdef CACHEDUMP
@@ -1436,6 +1529,7 @@ _dump_cache(Evas_Cache_Image *cache)
1436 cache->limit / 1024); 1529 cache->limit / 1024);
1437 printf("................................................................\n"); 1530 printf("................................................................\n");
1438 total = 0; 1531 total = 0;
1532 SLKL(engine_lock);
1439 EINA_INLIST_FOREACH(cache->lru_nodata, im) 1533 EINA_INLIST_FOREACH(cache->lru_nodata, im)
1440 _dump_img(im, "NODATA"); 1534 _dump_img(im, "NODATA");
1441 EINA_INLIST_FOREACH(cache->lru, im) 1535 EINA_INLIST_FOREACH(cache->lru, im)
@@ -1445,6 +1539,7 @@ _dump_cache(Evas_Cache_Image *cache)
1445 total, 1539 total,
1446 cache->usage); 1540 cache->usage);
1447 eina_hash_foreach(cache->activ, _dump_cache_active, NULL); 1541 eina_hash_foreach(cache->activ, _dump_cache_active, NULL);
1542 SLKU(engine_lock);
1448} 1543}
1449#endif 1544#endif
1450 1545
@@ -1456,6 +1551,7 @@ evas_cache_image_flush(Evas_Cache_Image *cache)
1456#endif 1551#endif
1457 if (cache->limit == (unsigned int)-1) return -1; 1552 if (cache->limit == (unsigned int)-1) return -1;
1458 1553
1554 SLKL(engine_lock);
1459 while ((cache->lru) && (cache->limit < (unsigned int)cache->usage)) 1555 while ((cache->lru) && (cache->limit < (unsigned int)cache->usage))
1460 { 1556 {
1461 Image_Entry *im; 1557 Image_Entry *im;
@@ -1475,6 +1571,7 @@ evas_cache_image_flush(Evas_Cache_Image *cache)
1475 cache->func.surface_delete(im); 1571 cache->func.surface_delete(im);
1476 im->flags.loaded = 0; 1572 im->flags.loaded = 0;
1477 } 1573 }
1574 SLKU(engine_lock);
1478 1575
1479 return cache->usage; 1576 return cache->usage;
1480} 1577}
@@ -1485,7 +1582,9 @@ evas_cache_image_empty(Evas_Cache_Image *cache)
1485 int err; 1582 int err;
1486 Image_Entry *im; 1583 Image_Entry *im;
1487 1584
1585 SLKL(engine_lock);
1488 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err); 1586 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL, &err);
1587 SLKU(engine_lock);
1489 if (!im) return NULL; 1588 if (!im) return NULL;
1490 im->references = 1; 1589 im->references = 1;
1491 return im; 1590 return im;
@@ -1494,16 +1593,23 @@ evas_cache_image_empty(Evas_Cache_Image *cache)
1494EAPI void 1593EAPI void
1495evas_cache_image_colorspace(Image_Entry *im, Evas_Colorspace cspace) 1594evas_cache_image_colorspace(Image_Entry *im, Evas_Colorspace cspace)
1496{ 1595{
1497 if (im->space == cspace) return; 1596 evas_cache_image_ref(im);
1597 if (im->space == cspace) goto done;
1498 im->space = cspace; 1598 im->space = cspace;
1499 if (!im->cache) return; 1599 if (!im->cache) goto done;
1500 im->cache->func.color_space(im, cspace); 1600 im->cache->func.color_space(im, cspace);
1601done:
1602 evas_cache_image_drop(im);
1501} 1603}
1502 1604
1503EAPI void * 1605EAPI void *
1504evas_cache_private_from_image_entry_get(Image_Entry *im) 1606evas_cache_private_from_image_entry_get(Image_Entry *im)
1505{ 1607{
1506 return (void *)im->cache->data; 1608 void *data;
1609 evas_cache_image_ref(im);
1610 data = (void *)im->cache->data;
1611 evas_cache_image_drop(im);
1612 return data;
1507} 1613}
1508 1614
1509EAPI void * 1615EAPI void *