From 5f0933f07a548719a850d9cac01aae6709b9dc0b Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 27 Oct 2016 09:51:10 +0200 Subject: Fix T49829: Removal of custom icon previews during add-on unregister crashes Blender. Issue was happening when removal of custom icons was done while they were still being rendered by preview job. Now add a 'deffered deletion' system, to prevent main thread to delete preview image until loading thread is done with them. Note that ideally, calling `ED_preview_kill_jobs()` on custom icon removal would have been simpler, but we don't have easy access to context here... --- source/blender/blenkernel/intern/icons.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'source/blender/blenkernel/intern/icons.c') diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index 2d5b15c8f9d..7669c4ba112 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -143,7 +143,7 @@ static PreviewImage *previewimg_create_ex(size_t deferred_data_size) memset(prv_img, 0, sizeof(*prv_img)); /* leave deferred data dirty */ if (deferred_data_size) { - prv_img->use_deferred = true; + prv_img->tag |= PRV_TAG_DEFFERED; } for (i = 0; i < NUM_ICON_SIZES; ++i) { @@ -355,11 +355,14 @@ PreviewImage *BKE_previewimg_cached_thumbnail_read( return prv; } -void BKE_previewimg_cached_release(const char *name) +void BKE_previewimg_cached_release_pointer(PreviewImage *prv) { - PreviewImage *prv = BLI_ghash_popkey(gCachedPreviews, name, MEM_freeN); - if (prv) { + if (prv->tag & PRV_TAG_DEFFERED_RENDERING) { + /* We cannot delete the preview while it is being loaded in another thread... */ + prv->tag |= PRV_TAG_DEFFERED_DELETE; + return; + } if (prv->icon_id) { BKE_icon_delete(prv->icon_id); } @@ -367,11 +370,18 @@ void BKE_previewimg_cached_release(const char *name) } } +void BKE_previewimg_cached_release(const char *name) +{ + PreviewImage *prv = BLI_ghash_popkey(gCachedPreviews, name, MEM_freeN); + + BKE_previewimg_cached_release_pointer(prv); +} + /** Handle deferred (lazy) loading/generation of preview image, if needed. * For now, only used with file thumbnails. */ void BKE_previewimg_ensure(PreviewImage *prv, const int size) { - if (prv->use_deferred) { + if ((prv->tag & PRV_TAG_DEFFERED) != 0) { const bool do_icon = ((size == ICON_SIZE_ICON) && !prv->rect[ICON_SIZE_ICON]); const bool do_preview = ((size == ICON_SIZE_PREVIEW) && !prv->rect[ICON_SIZE_PREVIEW]); -- cgit v1.2.3