diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2015-09-29 20:54:25 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-09-30 18:08:26 +0300 |
commit | ae4fcdc7ba74bc73e9ffd40de92c4f2a37a1f50f (patch) | |
tree | 9c5e1b9df55be8340ffa3f0c14bdf7b3094534a8 | |
parent | 24615ecab510c5d25a7b69a5259770eaddfed7ef (diff) |
Fix T46299: Windows: File Browser Crash while listing big folders in preview mode (fonts, images...).
Windows-only bug, mmap & co are not threadsafe by default on this platform, so we have to add a dedicated
spinlock for them in win32.
Note that we may try to get rid of those mmap later, but not for 2.76!
To be backported to final 2.76...
-rw-r--r-- | source/blender/imbuf/intern/IMB_allocimbuf.h | 12 | ||||
-rw-r--r-- | source/blender/imbuf/intern/allocimbuf.c | 24 | ||||
-rw-r--r-- | source/blender/imbuf/intern/module.c | 2 | ||||
-rw-r--r-- | source/blender/imbuf/intern/readimage.c | 11 |
4 files changed, 49 insertions, 0 deletions
diff --git a/source/blender/imbuf/intern/IMB_allocimbuf.h b/source/blender/imbuf/intern/IMB_allocimbuf.h index f4d6d869f1b..a754a4919eb 100644 --- a/source/blender/imbuf/intern/IMB_allocimbuf.h +++ b/source/blender/imbuf/intern/IMB_allocimbuf.h @@ -38,6 +38,18 @@ struct ImBuf; void imb_refcounter_lock_init(void); void imb_refcounter_lock_exit(void); +#ifdef WIN32 +void imb_mmap_lock_init(void); +void imb_mmap_lock_exit(void); +void imb_mmap_lock(void); +void imb_mmap_unlock(void); +#else +# define imb_mmap_lock_init() +# define imb_mmap_lock_exit() +# define imb_mmap_lock() +# define imb_mmap_unlock() +#endif + bool imb_addencodedbufferImBuf(struct ImBuf *ibuf); bool imb_enlargeencodedbufferImBuf(struct ImBuf *ibuf); diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c index 5c79eb2c544..19b68b17e70 100644 --- a/source/blender/imbuf/intern/allocimbuf.c +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -62,6 +62,30 @@ void imb_refcounter_lock_exit(void) BLI_spin_end(&refcounter_spin); } +#ifdef WIN32 +static SpinLock mmap_spin; + +void imb_mmap_lock_init(void) +{ + BLI_spin_init(&mmap_spin); +} + +void imb_mmap_lock_exit(void) +{ + BLI_spin_end(&mmap_spin); +} + +void imb_mmap_lock(void) +{ + BLI_spin_lock(&mmap_spin); +} + +void imb_mmap_unlock(void) +{ + BLI_spin_unlock(&mmap_spin); +} +#endif + void imb_freemipmapImBuf(ImBuf *ibuf) { int a; diff --git a/source/blender/imbuf/intern/module.c b/source/blender/imbuf/intern/module.c index 4097deb00ed..777fe77f032 100644 --- a/source/blender/imbuf/intern/module.c +++ b/source/blender/imbuf/intern/module.c @@ -37,6 +37,7 @@ void IMB_init(void) { imb_refcounter_lock_init(); + imb_mmap_lock_init(); imb_filetypes_init(); imb_tile_cache_init(); colormanagement_init(); @@ -47,6 +48,7 @@ void IMB_exit(void) imb_tile_cache_exit(); imb_filetypes_exit(); colormanagement_exit(); + imb_mmap_lock_exit(); imb_refcounter_lock_exit(); } diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c index 1c83b33e296..afa3ffb31f3 100644 --- a/source/blender/imbuf/intern/readimage.c +++ b/source/blender/imbuf/intern/readimage.c @@ -46,6 +46,7 @@ #include "BLI_fileops.h" #include "imbuf.h" +#include "IMB_allocimbuf.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" #include "IMB_filetype.h" @@ -174,7 +175,10 @@ ImBuf *IMB_loadifffile(int file, const char *filepath, int flags, char colorspac size = BLI_file_descriptor_size(file); + imb_mmap_lock(); mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0); + imb_mmap_unlock(); + if (mem == (unsigned char *) -1) { fprintf(stderr, "%s: couldn't get mapping %s\n", __func__, descr); return NULL; @@ -182,8 +186,10 @@ ImBuf *IMB_loadifffile(int file, const char *filepath, int flags, char colorspac ibuf = IMB_ibImageFromMemory(mem, size, flags, colorspace, descr); + imb_mmap_lock(); if (munmap(mem, size)) fprintf(stderr, "%s: couldn't unmap file %s\n", __func__, descr); + imb_mmap_unlock(); return ibuf; } @@ -269,7 +275,10 @@ static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int size = BLI_file_descriptor_size(file); + imb_mmap_lock(); mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0); + imb_mmap_unlock(); + if (mem == (unsigned char *) -1) { fprintf(stderr, "Couldn't get memory mapping for %s\n", ibuf->cachename); return; @@ -279,8 +288,10 @@ static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int if (type->load_tile && type->ftype(type, ibuf)) type->load_tile(ibuf, mem, size, tx, ty, rect); + imb_mmap_lock(); if (munmap(mem, size)) fprintf(stderr, "Couldn't unmap memory for %s.\n", ibuf->cachename); + imb_mmap_unlock(); } void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect) |