mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:37:35 +00:00
LibGfx: Make sure Bitmap::create_with_anon_fd() always closes if needed
If this is called with ShouldCloseAnonymousFile::Yes, it's entrusted with closing the anon_fd and nobody else will take care of it.
This commit is contained in:
parent
1a157d3f50
commit
f18d89b36d
1 changed files with 20 additions and 13 deletions
|
@ -28,6 +28,7 @@
|
||||||
#include <AK/Memory.h>
|
#include <AK/Memory.h>
|
||||||
#include <AK/MemoryStream.h>
|
#include <AK/MemoryStream.h>
|
||||||
#include <AK/Optional.h>
|
#include <AK/Optional.h>
|
||||||
|
#include <AK/ScopeGuard.h>
|
||||||
#include <AK/SharedBuffer.h>
|
#include <AK/SharedBuffer.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <LibGfx/BMPLoader.h>
|
#include <LibGfx/BMPLoader.h>
|
||||||
|
@ -188,22 +189,28 @@ static bool check_size(const IntSize& size, BitmapFormat format, unsigned actual
|
||||||
|
|
||||||
RefPtr<Bitmap> Bitmap::create_with_anon_fd(BitmapFormat format, int anon_fd, const IntSize& size, ShouldCloseAnonymousFile should_close_anon_fd)
|
RefPtr<Bitmap> Bitmap::create_with_anon_fd(BitmapFormat format, int anon_fd, const IntSize& size, ShouldCloseAnonymousFile should_close_anon_fd)
|
||||||
{
|
{
|
||||||
if (size_would_overflow(format, size))
|
void* data = nullptr;
|
||||||
return nullptr;
|
{
|
||||||
|
// If ShouldCloseAnonymousFile::Yes, it's our responsibility to close 'anon_fd' no matter what.
|
||||||
|
ScopeGuard close_guard = [&] {
|
||||||
|
if (should_close_anon_fd == ShouldCloseAnonymousFile::Yes) {
|
||||||
|
int rc = close(anon_fd);
|
||||||
|
ASSERT(rc == 0);
|
||||||
|
anon_fd = -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const auto pitch = minimum_pitch(size.width(), format);
|
if (size_would_overflow(format, size))
|
||||||
const auto data_size_in_bytes = size_in_bytes(pitch, size.height());
|
return nullptr;
|
||||||
|
|
||||||
auto* data = mmap(nullptr, round_up_to_power_of_two(data_size_in_bytes, PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, anon_fd, 0);
|
const auto pitch = minimum_pitch(size.width(), format);
|
||||||
if (data == MAP_FAILED) {
|
const auto data_size_in_bytes = size_in_bytes(pitch, size.height());
|
||||||
perror("mmap");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (should_close_anon_fd == ShouldCloseAnonymousFile::Yes) {
|
data = mmap(nullptr, round_up_to_power_of_two(data_size_in_bytes, PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, anon_fd, 0);
|
||||||
int rc = close(anon_fd);
|
if (data == MAP_FAILED) {
|
||||||
ASSERT(rc == 0);
|
perror("mmap");
|
||||||
anon_fd = -1;
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return adopt(*new Bitmap(format, anon_fd, size, data));
|
return adopt(*new Bitmap(format, anon_fd, size, data));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue