From 43f930d3aacf64b4cbf28e95bd4ef8292e2e6011 Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Sun, 1 Aug 2021 01:54:09 -0700 Subject: [PATCH] Kernel: Convert MasterPTY creation to use DoubleBuffer factory In order to remove the public DoubleBuffer constructor, we need to convert the callers to the factory instead, allowing the caller to observe OOM. --- Kernel/TTY/MasterPTY.cpp | 35 +++++++++++++++++++++++++++-------- Kernel/TTY/MasterPTY.h | 5 +++-- Kernel/TTY/PTYMultiplexer.cpp | 2 +- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/Kernel/TTY/MasterPTY.cpp b/Kernel/TTY/MasterPTY.cpp index 2179d7c90f..dea6557f91 100644 --- a/Kernel/TTY/MasterPTY.cpp +++ b/Kernel/TTY/MasterPTY.cpp @@ -16,17 +16,36 @@ namespace Kernel { -MasterPTY::MasterPTY(unsigned index) +RefPtr MasterPTY::try_create(unsigned int index) +{ + auto buffer = DoubleBuffer::try_create(); + if (!buffer) + return {}; + + auto master_pty = adopt_ref_if_nonnull(new (nothrow) MasterPTY(index, buffer.release_nonnull())); + if (!master_pty) + return {}; + + auto slave_pty = adopt_ref_if_nonnull(new (nothrow) SlavePTY(*master_pty, index)); + if (!slave_pty) + return {}; + + master_pty->m_slave = slave_pty; + + return master_pty; +} + +MasterPTY::MasterPTY(unsigned index, NonnullOwnPtr buffer) : CharacterDevice(200, index) - , m_slave(adopt_ref(*new SlavePTY(*this, index))) , m_index(index) + , m_buffer(move(buffer)) { m_pts_name = String::formatted("/dev/pts/{}", m_index); auto process = Process::current(); set_uid(process->uid()); set_gid(process->gid()); - m_buffer.set_unblock_callback([this]() { + m_buffer->set_unblock_callback([this]() { if (m_slave) evaluate_block_conditions(); }); @@ -45,9 +64,9 @@ String MasterPTY::pts_name() const KResultOr MasterPTY::read(FileDescription&, u64, UserOrKernelBuffer& buffer, size_t size) { - if (!m_slave && m_buffer.is_empty()) + if (!m_slave && m_buffer->is_empty()) return 0; - return m_buffer.read(buffer, size); + return m_buffer->read(buffer, size); } KResultOr MasterPTY::write(FileDescription&, u64, const UserOrKernelBuffer& buffer, size_t size) @@ -62,7 +81,7 @@ bool MasterPTY::can_read(const FileDescription&, size_t) const { if (!m_slave) return true; - return !m_buffer.is_empty(); + return !m_buffer->is_empty(); } bool MasterPTY::can_write(const FileDescription&, size_t) const @@ -83,14 +102,14 @@ KResultOr MasterPTY::on_slave_write(const UserOrKernelBuffer& data, size { if (m_closed) return EIO; - return m_buffer.write(data, size); + return m_buffer->write(data, size); } bool MasterPTY::can_write_from_slave() const { if (m_closed) return true; - return m_buffer.space_for_writing(); + return m_buffer->space_for_writing(); } KResult MasterPTY::close() diff --git a/Kernel/TTY/MasterPTY.h b/Kernel/TTY/MasterPTY.h index a1c9274046..5ec21dced4 100644 --- a/Kernel/TTY/MasterPTY.h +++ b/Kernel/TTY/MasterPTY.h @@ -16,7 +16,7 @@ class SlavePTY; class MasterPTY final : public CharacterDevice { public: - explicit MasterPTY(unsigned index); + [[nodiscard]] static RefPtr try_create(unsigned index); virtual ~MasterPTY() override; unsigned index() const { return m_index; } @@ -33,6 +33,7 @@ public: virtual String device_name() const override; private: + explicit MasterPTY(unsigned index, NonnullOwnPtr buffer); // ^CharacterDevice virtual KResultOr read(FileDescription&, u64, UserOrKernelBuffer&, size_t) override; virtual KResultOr write(FileDescription&, u64, const UserOrKernelBuffer&, size_t) override; @@ -46,7 +47,7 @@ private: RefPtr m_slave; unsigned m_index; bool m_closed { false }; - DoubleBuffer m_buffer; + NonnullOwnPtr m_buffer; String m_pts_name; }; diff --git a/Kernel/TTY/PTYMultiplexer.cpp b/Kernel/TTY/PTYMultiplexer.cpp index 50ad2133e8..0f0dae7415 100644 --- a/Kernel/TTY/PTYMultiplexer.cpp +++ b/Kernel/TTY/PTYMultiplexer.cpp @@ -40,7 +40,7 @@ KResultOr> PTYMultiplexer::open(int options) if (m_freelist.is_empty()) return EBUSY; auto master_index = m_freelist.take_last(); - auto master = try_create(master_index); + auto master = MasterPTY::try_create(master_index); if (!master) return ENOMEM; dbgln_if(PTMX_DEBUG, "PTYMultiplexer::open: Vending master {}", master->index());