diff options
author | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2017-03-09 11:18:32 +0900 |
---|---|---|
committer | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2017-03-09 11:21:19 +0900 |
commit | d550190d6be8fe4d1ba44042ad8d9c17cf232079 (patch) | |
tree | a6d95f2034e6a6af8aa8259f9802fdc0328c10b5 | |
parent | 1a5563ab636ee37bea39d68d0da04114c2ac6245 (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.c | 156 |
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 | |||
328 | evas_cache_image_cancelled(void *data) | 322 | evas_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 | ||
335 | static void | 333 | static 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 | ||
584 | EAPI int | 597 | EAPI 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 | ||
991 | on_ok: | 1016 | on_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 | ||
996 | on_stat_error: | 1024 | on_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 | ||
1018 | EAPI void | 1047 | EAPI void |
1019 | evas_cache_image_ref(Image_Entry *im) | 1048 | evas_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 | ||
1024 | EAPI void | 1057 | EAPI 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 | ||
1067 | EAPI Image_Entry * | 1110 | EAPI 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 | ||
1238 | on_error: | 1301 | on_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 | ||
1291 | EAPI void | 1367 | EAPI void |
1292 | evas_cache_image_unload_data(Image_Entry *im) | 1368 | evas_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 | ||
1337 | static int async_frozen = 0; | 1425 | static 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 | ||
1398 | EAPI void | 1489 | EAPI void |
1399 | evas_cache_image_preload_cancel(Image_Entry *im, const Eo *target) | 1490 | evas_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) | |||
1494 | EAPI void | 1593 | EAPI void |
1495 | evas_cache_image_colorspace(Image_Entry *im, Evas_Colorspace cspace) | 1594 | evas_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); |
1601 | done: | ||
1602 | evas_cache_image_drop(im); | ||
1501 | } | 1603 | } |
1502 | 1604 | ||
1503 | EAPI void * | 1605 | EAPI void * |
1504 | evas_cache_private_from_image_entry_get(Image_Entry *im) | 1606 | evas_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 | ||
1509 | EAPI void * | 1615 | EAPI void * |