mirror of https://github.com/mgba-emu/mgba.git
VFS: Fix handle leak when double-mapping (fixes #1659)
This commit is contained in:
parent
6b12eddfba
commit
baeb353694
1
CHANGES
1
CHANGES
|
@ -31,6 +31,7 @@ Other fixes:
|
||||||
- Qt: Fix window title not updating after shutting down game
|
- Qt: Fix window title not updating after shutting down game
|
||||||
- Qt: Fix GIF view not allowing manual filename entry
|
- Qt: Fix GIF view not allowing manual filename entry
|
||||||
- Util: Fix crash reading invalid ELFs
|
- Util: Fix crash reading invalid ELFs
|
||||||
|
- VFS: Fix handle leak when double-mapping (fixes mgba.io/i/1659)
|
||||||
Misc:
|
Misc:
|
||||||
- FFmpeg: Add more presets
|
- FFmpeg: Add more presets
|
||||||
- Qt: Renderer can be changed while a game is running
|
- Qt: Renderer can be changed while a game is running
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2013-2015 Jeffrey Pfau
|
/* Copyright (c) 2013-2020 Jeffrey Pfau
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
@ -14,11 +14,23 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <mgba-util/vector.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
struct HandleMappingTuple {
|
||||||
|
HANDLE handle;
|
||||||
|
void* mapping;
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_VECTOR(HandleMappingList, struct HandleMappingTuple);
|
||||||
|
DEFINE_VECTOR(HandleMappingList, struct HandleMappingTuple);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct VFileFD {
|
struct VFileFD {
|
||||||
struct VFile d;
|
struct VFile d;
|
||||||
int fd;
|
int fd;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HANDLE hMap;
|
struct HandleMappingList handles;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,12 +86,23 @@ struct VFile* VFileFromFD(int fd) {
|
||||||
vfd->d.truncate = _vfdTruncate;
|
vfd->d.truncate = _vfdTruncate;
|
||||||
vfd->d.size = _vfdSize;
|
vfd->d.size = _vfdSize;
|
||||||
vfd->d.sync = _vfdSync;
|
vfd->d.sync = _vfdSync;
|
||||||
|
#ifdef _WIN32
|
||||||
|
HandleMappingListInit(&vfd->handles, 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
return &vfd->d;
|
return &vfd->d;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _vfdClose(struct VFile* vf) {
|
bool _vfdClose(struct VFile* vf) {
|
||||||
struct VFileFD* vfd = (struct VFileFD*) vf;
|
struct VFileFD* vfd = (struct VFileFD*) vf;
|
||||||
|
#ifdef _WIN32
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < HandleMappingListSize(&vfd->handles); ++i) {
|
||||||
|
UnmapViewOfFile(HandleMappingListGetPointer(&vfd->handles, i)->mapping);
|
||||||
|
CloseHandle(HandleMappingListGetPointer(&vfd->handles, i)->handle);
|
||||||
|
}
|
||||||
|
HandleMappingListDeinit(&vfd->handles);
|
||||||
|
#endif
|
||||||
if (close(vfd->fd) < 0) {
|
if (close(vfd->fd) < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -134,16 +157,25 @@ static void* _vfdMap(struct VFile* vf, size_t size, int flags) {
|
||||||
if (size > fileSize) {
|
if (size > fileSize) {
|
||||||
size = fileSize;
|
size = fileSize;
|
||||||
}
|
}
|
||||||
vfd->hMap = CreateFileMapping((HANDLE) _get_osfhandle(vfd->fd), 0, createFlags, 0, size & 0xFFFFFFFF, 0);
|
struct HandleMappingTuple tuple = {0};
|
||||||
return MapViewOfFile(vfd->hMap, mapFiles, 0, 0, size);
|
tuple.handle = CreateFileMapping((HANDLE) _get_osfhandle(vfd->fd), 0, createFlags, 0, size & 0xFFFFFFFF, 0);
|
||||||
|
tuple.mapping = MapViewOfFile(tuple.handle, mapFiles, 0, 0, size);
|
||||||
|
*HandleMappingListAppend(&vfd->handles) = tuple;
|
||||||
|
return tuple.mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _vfdUnmap(struct VFile* vf, void* memory, size_t size) {
|
static void _vfdUnmap(struct VFile* vf, void* memory, size_t size) {
|
||||||
UNUSED(size);
|
UNUSED(size);
|
||||||
struct VFileFD* vfd = (struct VFileFD*) vf;
|
struct VFileFD* vfd = (struct VFileFD*) vf;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < HandleMappingListSize(&vfd->handles); ++i) {
|
||||||
|
if (HandleMappingListGetPointer(&vfd->handles, i)->mapping == memory) {
|
||||||
|
CloseHandle(HandleMappingListGetPointer(&vfd->handles, i)->handle);
|
||||||
|
HandleMappingListShift(&vfd->handles, i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
UnmapViewOfFile(memory);
|
UnmapViewOfFile(memory);
|
||||||
CloseHandle(vfd->hMap);
|
|
||||||
vfd->hMap = 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue