Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2015-09-29 20:54:25 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-09-30 18:08:26 +0300
commitae4fcdc7ba74bc73e9ffd40de92c4f2a37a1f50f (patch)
tree9c5e1b9df55be8340ffa3f0c14bdf7b3094534a8
parent24615ecab510c5d25a7b69a5259770eaddfed7ef (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.h12
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c24
-rw-r--r--source/blender/imbuf/intern/module.c2
-rw-r--r--source/blender/imbuf/intern/readimage.c11
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)