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...
This commit is contained in:
Bastien Montagne 2015-09-29 19:54:25 +02:00 committed by Sergey Sharybin
parent 24615ecab5
commit ae4fcdc7ba
4 changed files with 49 additions and 0 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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();
}

View File

@ -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)