LibCore: Use ErrorOr<T> in Core::AnonymousBuffer

This commit is contained in:
Andreas Kling 2021-11-06 01:20:51 +01:00
parent c4edb9f6c2
commit e2eabb4132
Notes: sideshowbarker 2024-07-18 01:25:13 +09:00
15 changed files with 56 additions and 53 deletions

View file

@ -181,7 +181,7 @@ public:
private:
explicit Buffer(const Vector<Frame> samples)
: m_buffer(Core::AnonymousBuffer::create_with_size(samples.size() * sizeof(Frame)))
: m_buffer(Core::AnonymousBuffer::create_with_size(samples.size() * sizeof(Frame)).release_value())
, m_id(allocate_id())
, m_sample_count(samples.size())
{

View file

@ -4,10 +4,10 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Try.h>
#include <LibCore/AnonymousBuffer.h>
#include <LibIPC/File.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>
#if defined(__serenity__)
@ -26,40 +26,33 @@ static int memfd_create(const char* name, unsigned int flags)
namespace Core {
AnonymousBuffer AnonymousBuffer::create_with_size(size_t size)
ErrorOr<AnonymousBuffer> AnonymousBuffer::create_with_size(size_t size)
{
int fd = -1;
#if defined(__serenity__)
fd = anon_create(round_up_to_power_of_two(size, PAGE_SIZE), O_CLOEXEC);
if (fd < 0) {
perror("anon_create");
return {};
}
if (fd < 0)
return AK::Error::from_errno(errno);
#elif defined(__linux__)
fd = memfd_create("", MFD_CLOEXEC);
if (fd < 0) {
perror("memfd_create");
return {};
}
if (fd < 0)
return Error::from_errno(errno);
if (ftruncate(fd, size) < 0) {
close(fd);
perror("ftruncate");
return {};
return Error::from_errno(errno);
}
#endif
if (fd < 0)
return {};
return AK::Error::from_errno(errno);
return create_from_anon_fd(fd, size);
}
RefPtr<AnonymousBufferImpl> AnonymousBufferImpl::create(int fd, size_t size)
ErrorOr<NonnullRefPtr<AnonymousBufferImpl>> AnonymousBufferImpl::create(int fd, size_t size)
{
auto* data = mmap(nullptr, round_up_to_power_of_two(size, PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0);
if (data == MAP_FAILED) {
perror("mmap");
return {};
}
return adopt_ref(*new AnonymousBufferImpl(fd, size, data));
if (data == MAP_FAILED)
return AK::Error::from_errno(errno);
return AK::adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousBufferImpl(fd, size, data));
}
AnonymousBufferImpl::~AnonymousBufferImpl()
@ -72,12 +65,10 @@ AnonymousBufferImpl::~AnonymousBufferImpl()
VERIFY(rc == 0);
}
AnonymousBuffer AnonymousBuffer::create_from_anon_fd(int fd, size_t size)
ErrorOr<AnonymousBuffer> AnonymousBuffer::create_from_anon_fd(int fd, size_t size)
{
auto impl = AnonymousBufferImpl::create(fd, size);
if (!impl)
return {};
return AnonymousBuffer(impl.release_nonnull());
auto impl = TRY(AnonymousBufferImpl::create(fd, size));
return AnonymousBuffer(move(impl));
}
AnonymousBuffer::AnonymousBuffer(NonnullRefPtr<AnonymousBufferImpl> impl)

View file

@ -6,6 +6,7 @@
#pragma once
#include <AK/Error.h>
#include <AK/Noncopyable.h>
#include <AK/RefCounted.h>
#include <AK/RefPtr.h>
@ -16,7 +17,7 @@ namespace Core {
class AnonymousBufferImpl final : public RefCounted<AnonymousBufferImpl> {
public:
static RefPtr<AnonymousBufferImpl> create(int fd, size_t);
static ErrorOr<NonnullRefPtr<AnonymousBufferImpl>> create(int fd, size_t);
~AnonymousBufferImpl();
int fd() const { return m_fd; }
@ -34,8 +35,8 @@ private:
class AnonymousBuffer {
public:
static AnonymousBuffer create_with_size(size_t);
static AnonymousBuffer create_from_anon_fd(int fd, size_t);
static ErrorOr<AnonymousBuffer> create_with_size(size_t);
static ErrorOr<AnonymousBuffer> create_from_anon_fd(int fd, size_t);
AnonymousBuffer() { }

View file

@ -106,11 +106,12 @@ RefPtr<Gfx::Bitmap> Clipboard::bitmap() const
void Clipboard::set_data(ReadonlyBytes const& data, String const& type, HashMap<String, String> const& metadata)
{
auto buffer = Core::AnonymousBuffer::create_with_size(data.size());
if (!buffer.is_valid()) {
auto buffer_or_error = Core::AnonymousBuffer::create_with_size(data.size());
if (buffer_or_error.is_error()) {
dbgln("GUI::Clipboard::set_data() failed to create a buffer");
return;
}
auto buffer = buffer_or_error.release_value();
if (!data.is_empty())
memcpy(buffer.data<void>(), data.data(), data.size());

View file

@ -862,14 +862,14 @@ OwnPtr<WindowBackingStore> Window::create_backing_store(const Gfx::IntSize& size
size_t pitch = Gfx::Bitmap::minimum_pitch(size.width(), format);
size_t size_in_bytes = size.height() * pitch;
auto buffer = Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(size_in_bytes, PAGE_SIZE));
if (!buffer.is_valid()) {
auto buffer_or_error = Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(size_in_bytes, PAGE_SIZE));
if (buffer_or_error.is_error()) {
perror("anon_create");
return {};
}
// FIXME: Plumb scale factor here eventually.
auto bitmap = Gfx::Bitmap::try_create_with_anonymous_buffer(format, move(buffer), size, 1, {});
auto bitmap = Gfx::Bitmap::try_create_with_anonymous_buffer(format, buffer_or_error.release_value(), size, 1, {});
if (!bitmap) {
VERIFY(size.width() <= INT16_MAX);
VERIFY(size.height() <= INT16_MAX);

View file

@ -81,10 +81,10 @@ RefPtr<Bitmap> Bitmap::try_create_shareable(BitmapFormat format, const IntSize&
const auto pitch = minimum_pitch(size.width() * scale_factor, format);
const auto data_size = size_in_bytes(pitch, size.height() * scale_factor);
auto buffer = Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(data_size, PAGE_SIZE));
if (!buffer.is_valid())
auto buffer_or_error = Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(data_size, PAGE_SIZE));
if (buffer_or_error.is_error())
return nullptr;
return Bitmap::try_create_with_anonymous_buffer(format, buffer, size, scale_factor, {});
return Bitmap::try_create_with_anonymous_buffer(format, buffer_or_error.release_value(), size, scale_factor, {});
}
Bitmap::Bitmap(BitmapFormat format, const IntSize& size, int scale_factor, const BackingStore& backing_store)
@ -525,10 +525,10 @@ RefPtr<Bitmap> Bitmap::to_bitmap_backed_by_anonymous_buffer() const
{
if (m_buffer.is_valid())
return *this;
auto buffer = Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(size_in_bytes(), PAGE_SIZE));
if (!buffer.is_valid())
auto buffer_or_error = Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(size_in_bytes(), PAGE_SIZE));
if (buffer_or_error.is_error())
return nullptr;
auto bitmap = Bitmap::try_create_with_anonymous_buffer(m_format, move(buffer), size(), scale(), palette_to_vector());
auto bitmap = Bitmap::try_create_with_anonymous_buffer(m_format, buffer_or_error.release_value(), size(), scale(), palette_to_vector());
if (!bitmap)
return nullptr;
memcpy(bitmap->scanline(0), scanline(0), size_in_bytes());

View file

@ -44,7 +44,7 @@ String PaletteImpl::path(PathRole role) const
NonnullRefPtr<PaletteImpl> PaletteImpl::clone() const
{
auto new_theme_buffer = Core::AnonymousBuffer::create_with_size(m_theme_buffer.size());
auto new_theme_buffer = Core::AnonymousBuffer::create_with_size(m_theme_buffer.size()).release_value();
memcpy(new_theme_buffer.data<SystemTheme>(), &theme(), m_theme_buffer.size());
return adopt_ref(*new PaletteImpl(move(new_theme_buffer)));
}

View file

@ -73,10 +73,10 @@ bool decode(Decoder& decoder, Gfx::ShareableBitmap& shareable_bitmap)
if (!decoder.decode(palette))
return false;
}
auto buffer = Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), Gfx::Bitmap::size_in_bytes(Gfx::Bitmap::minimum_pitch(size.width(), bitmap_format), size.height()));
if (!buffer.is_valid())
auto buffer_or_error = Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), Gfx::Bitmap::size_in_bytes(Gfx::Bitmap::minimum_pitch(size.width(), bitmap_format), size.height()));
if (buffer_or_error.is_error())
return false;
auto bitmap = Gfx::Bitmap::try_create_with_anonymous_buffer(bitmap_format, buffer, size, scale, palette);
auto bitmap = Gfx::Bitmap::try_create_with_anonymous_buffer(bitmap_format, buffer_or_error.release_value(), size, scale, palette);
if (!bitmap)
return false;
shareable_bitmap = Gfx::ShareableBitmap { bitmap.release_nonnull(), Gfx::ShareableBitmap::ConstructWithKnownGoodBitmap };

View file

@ -29,7 +29,7 @@ void set_system_theme(Core::AnonymousBuffer buffer)
Core::AnonymousBuffer load_system_theme(Core::ConfigFile const& file)
{
auto buffer = Core::AnonymousBuffer::create_with_size(sizeof(SystemTheme));
auto buffer = Core::AnonymousBuffer::create_with_size(sizeof(SystemTheme)).release_value();
auto* data = buffer.data<SystemTheme>();

View file

@ -193,7 +193,10 @@ bool decode(Decoder& decoder, Core::AnonymousBuffer& buffer)
if (!decoder.decode(anon_file))
return false;
buffer = Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), size);
auto new_buffer_or_error = Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), size);
if (new_buffer_or_error.is_error())
return false;
buffer = new_buffer_or_error.release_value();
return buffer.is_valid();
}

View file

@ -25,11 +25,12 @@ Optional<DecodedImage> Client::decode_image(const ReadonlyBytes& encoded_data)
if (encoded_data.is_empty())
return {};
auto encoded_buffer = Core::AnonymousBuffer::create_with_size(encoded_data.size());
if (!encoded_buffer.is_valid()) {
auto encoded_buffer_or_error = Core::AnonymousBuffer::create_with_size(encoded_data.size());
if (encoded_buffer_or_error.is_error()) {
dbgln("Could not allocate encoded buffer");
return {};
}
auto encoded_buffer = encoded_buffer_or_error.release_value();
memcpy(encoded_buffer.data<void>(), encoded_data.data(), encoded_data.size());
auto response_or_error = try_decode_image(move(encoded_buffer));

View file

@ -62,7 +62,9 @@ void ClipboardServerConnection::set_bitmap(Gfx::Bitmap const& bitmap)
metadata.set("format", String::number((int)bitmap.format()));
metadata.set("pitch", String::number(bitmap.pitch()));
ReadonlyBytes data { bitmap.scanline(0), bitmap.size_in_bytes() };
auto buffer = Core::AnonymousBuffer::create_with_size(bitmap.size_in_bytes());
auto buffer_or_error = Core::AnonymousBuffer::create_with_size(bitmap.size_in_bytes());
VERIFY(!buffer_or_error.is_error());
auto buffer = buffer_or_error.release_value();
memcpy(buffer.data<u8>(), data.data(), data.size());
this->async_set_clipboard_data(buffer, "image/x-serenityos", metadata);
}

View file

@ -133,7 +133,9 @@ void SpiceAgent::on_message_received()
m_just_set_clip = true;
if (type == ClipboardType::Text) {
auto anon_buffer = Core::AnonymousBuffer::create_with_size(data_buffer.size());
auto anon_buffer_or_error = Core::AnonymousBuffer::create_with_size(data_buffer.size());
VERIFY(!anon_buffer_or_error.is_error());
auto anon_buffer = anon_buffer_or_error.release_value();
memcpy(anon_buffer.data<void>(), data_buffer.data(), data_buffer.size());
m_clipboard_connection.async_set_clipboard_data(anon_buffer, "text/plain", {});
return;

View file

@ -34,7 +34,9 @@ PageHost::~PageHost()
void PageHost::setup_palette()
{
// FIXME: Get the proper palette from our peer somehow
auto buffer = Core::AnonymousBuffer::create_with_size(sizeof(Gfx::SystemTheme));
auto buffer_or_error = Core::AnonymousBuffer::create_with_size(sizeof(Gfx::SystemTheme));
VERIFY(!buffer_or_error.is_error());
auto buffer = buffer_or_error.release_value();
auto* theme = buffer.data<Gfx::SystemTheme>();
theme->color[(int)Gfx::ColorRole::Window] = Color::Magenta;
theme->color[(int)Gfx::ColorRole::WindowText] = Color::Cyan;

View file

@ -635,14 +635,14 @@ void ClientConnection::set_window_backing_store(i32 window_id, [[maybe_unused]]
window.swap_backing_stores();
} else {
// FIXME: Plumb scale factor here eventually.
Core::AnonymousBuffer buffer = Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), pitch * size.height());
if (!buffer.is_valid()) {
auto buffer_or_error = Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), pitch * size.height());
if (buffer_or_error.is_error()) {
did_misbehave("SetWindowBackingStore: Failed to create anonymous buffer for window backing store");
return;
}
auto backing_store = Gfx::Bitmap::try_create_with_anonymous_buffer(
has_alpha_channel ? Gfx::BitmapFormat::BGRA8888 : Gfx::BitmapFormat::BGRx8888,
move(buffer),
buffer_or_error.release_value(),
size,
1,
{});