mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-01-08 17:47:18 +00:00
Before this change, we were passing them as Gfx::ShareableBitmap. The problem is that shareable bitmaps keep their underlying file descriptor open, so that they can be shared again with someone else. When a Gfx::Bitmap is decoded from an IPC message, the file descriptor is closed and recovered immediately. This fixes an issue where we'd accumulate one file descriptor for every image decoded. This eventually led to descriptor starvation after enough images were loaded and still referenced at the same time.
53 lines
1.6 KiB
C++
53 lines
1.6 KiB
C++
/*
|
|
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/HashMap.h>
|
|
#include <ImageDecoder/Forward.h>
|
|
#include <ImageDecoder/ImageDecoderClientEndpoint.h>
|
|
#include <ImageDecoder/ImageDecoderServerEndpoint.h>
|
|
#include <LibIPC/ConnectionFromClient.h>
|
|
#include <LibThreading/BackgroundAction.h>
|
|
|
|
namespace ImageDecoder {
|
|
|
|
class ConnectionFromClient final
|
|
: public IPC::ConnectionFromClient<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint> {
|
|
C_OBJECT(ConnectionFromClient);
|
|
|
|
public:
|
|
~ConnectionFromClient() override = default;
|
|
|
|
virtual void die() override;
|
|
|
|
struct DecodeResult {
|
|
bool is_animated = false;
|
|
u32 loop_count = 0;
|
|
Gfx::FloatPoint scale { 1, 1 };
|
|
Vector<Optional<NonnullRefPtr<Gfx::Bitmap>>> bitmaps;
|
|
Vector<u32> durations;
|
|
};
|
|
|
|
private:
|
|
using Job = Threading::BackgroundAction<DecodeResult>;
|
|
|
|
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>);
|
|
|
|
virtual Messages::ImageDecoderServer::DecodeImageResponse decode_image(Core::AnonymousBuffer const&, Optional<Gfx::IntSize> const& ideal_size, Optional<ByteString> const& mime_type) override;
|
|
virtual void cancel_decoding(i64 image_id) override;
|
|
virtual Messages::ImageDecoderServer::ConnectNewClientsResponse connect_new_clients(size_t count) override;
|
|
|
|
ErrorOr<IPC::File> connect_new_client();
|
|
|
|
NonnullRefPtr<Job> make_decode_image_job(i64 image_id, Core::AnonymousBuffer, Optional<Gfx::IntSize> ideal_size, Optional<ByteString> mime_type);
|
|
|
|
i64 m_next_image_id { 0 };
|
|
HashMap<i64, NonnullRefPtr<Job>> m_pending_jobs;
|
|
};
|
|
|
|
}
|