Fix #139387: Try to handle mmap exception on Win32
`IMB_load_image_from_file_descriptor` use mmap to read images, and mmap sometimes can have erroreous state llike accessing a file from network drives. This patch tries to handle these exceptions like `BLI_mmap_read` on Win32 (On unix the `sigbus_handler` will be called instead). Pull Request: https://projects.blender.org/blender/blender/pulls/139472
This commit is contained in:
@@ -30,5 +30,6 @@ bool BLI_mmap_read(BLI_mmap_file *file, void *dest, size_t offset, size_t length
|
||||
|
||||
void *BLI_mmap_get_pointer(BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT;
|
||||
size_t BLI_mmap_get_length(const BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT;
|
||||
bool BLI_mmap_any_io_error(const BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT;
|
||||
|
||||
void BLI_mmap_free(BLI_mmap_file *file) ATTR_NONNULL(1);
|
||||
|
||||
@@ -219,6 +219,11 @@ size_t BLI_mmap_get_length(const BLI_mmap_file *file)
|
||||
return file->length;
|
||||
}
|
||||
|
||||
bool BLI_mmap_any_io_error(const BLI_mmap_file *file)
|
||||
{
|
||||
return file->io_error;
|
||||
}
|
||||
|
||||
void BLI_mmap_free(BLI_mmap_file *file)
|
||||
{
|
||||
#ifndef WIN32
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <exception>
|
||||
# include <io.h>
|
||||
# include <stddef.h>
|
||||
# include <sys/types.h>
|
||||
@@ -167,7 +168,30 @@ ImBuf *IMB_load_image_from_file_descriptor(const int file,
|
||||
const uchar *mem = static_cast<const uchar *>(BLI_mmap_get_pointer(mmap_file));
|
||||
const size_t size = BLI_mmap_get_length(mmap_file);
|
||||
|
||||
ibuf = IMB_load_image_from_memory(mem, size, flags, filepath, filepath, r_colorspace);
|
||||
/* There could be broken mmap due to network drives and other issues, handles exception the
|
||||
* same way as in #BLI_mmap_read. Note that if the mmap becomes invalid mid-way through reading,
|
||||
* external calls in #IMB_load_image_from_memory could leave unfreed memory, but this is the
|
||||
* limitation of current exception handling method. Ref #139472. */
|
||||
#ifdef WIN32
|
||||
__try
|
||||
{
|
||||
#endif
|
||||
|
||||
ibuf = IMB_load_image_from_memory(mem, size, flags, filepath, filepath, r_colorspace);
|
||||
|
||||
#ifdef WIN32
|
||||
}
|
||||
__except (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR ? EXCEPTION_EXECUTE_HANDLER :
|
||||
EXCEPTION_CONTINUE_SEARCH)
|
||||
{
|
||||
ibuf = nullptr;
|
||||
}
|
||||
#else
|
||||
/* For unix, if mmap encounters an exception, BLI_mmap_file::io_error would be set. */
|
||||
if (BLI_mmap_any_io_error(mmap_file)) {
|
||||
ibuf = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
imb_mmap_lock();
|
||||
BLI_mmap_free(mmap_file);
|
||||
|
||||
Reference in New Issue
Block a user