ladybird/Kernel/TTY/PTYMultiplexer.cpp
Liav A 25bb293629 Kernel: Make Device::after_inserting to return ErrorOr<void>
Instead of just returning nothing, let's return Error or nothing.
This would help later on with error propagation in case of failure
during this method.

This also makes us more paranoid about failure in this method, so when
initializing a DisplayConnector we safely tear down the internal members
of the object. This applies the same for a StorageDevice object, but its
after_inserting method is much smaller compared to the DisplayConnector
overriden method.
2023-01-07 11:45:08 -07:00

65 lines
1.8 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Singleton.h>
#include <Kernel/API/POSIX/errno.h>
#include <Kernel/Debug.h>
#include <Kernel/FileSystem/OpenFileDescription.h>
#include <Kernel/Sections.h>
#include <Kernel/TTY/MasterPTY.h>
#include <Kernel/TTY/PTYMultiplexer.h>
namespace Kernel {
static Singleton<PTYMultiplexer> s_the;
PTYMultiplexer& PTYMultiplexer::the()
{
return *s_the;
}
UNMAP_AFTER_INIT PTYMultiplexer::PTYMultiplexer()
: CharacterDevice(5, 2)
{
m_freelist.with([&](auto& freelist) {
freelist.ensure_capacity(max_pty_pairs);
for (int i = max_pty_pairs; i > 0; --i)
freelist.unchecked_append(i - 1);
});
}
UNMAP_AFTER_INIT PTYMultiplexer::~PTYMultiplexer() = default;
UNMAP_AFTER_INIT void PTYMultiplexer::initialize()
{
MUST(the().after_inserting());
}
ErrorOr<NonnullLockRefPtr<OpenFileDescription>> PTYMultiplexer::open(int options)
{
return m_freelist.with([&](auto& freelist) -> ErrorOr<NonnullLockRefPtr<OpenFileDescription>> {
if (freelist.is_empty())
return EBUSY;
auto master_index = freelist.take_last();
auto master = TRY(MasterPTY::try_create(master_index));
dbgln_if(PTMX_DEBUG, "PTYMultiplexer::open: Vending master {}", master->index());
auto description = TRY(OpenFileDescription::try_create(*master));
description->set_rw_mode(options);
description->set_file_flags(options);
return description;
});
}
void PTYMultiplexer::notify_master_destroyed(Badge<MasterPTY>, unsigned index)
{
m_freelist.with([&](auto& freelist) {
freelist.append(index);
dbgln_if(PTMX_DEBUG, "PTYMultiplexer: {} added to freelist", index);
});
}
}