mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 17:55:09 +00:00
Kernel: Handle OOM from DoubleBuffer creation in FIFO creation
This commit is contained in:
parent
15cd5d324c
commit
8d3b819daf
4 changed files with 25 additions and 16 deletions
|
@ -24,9 +24,12 @@ static Lockable<HashTable<FIFO*>>& all_fifos()
|
||||||
|
|
||||||
static int s_next_fifo_id = 1;
|
static int s_next_fifo_id = 1;
|
||||||
|
|
||||||
NonnullRefPtr<FIFO> FIFO::create(uid_t uid)
|
RefPtr<FIFO> FIFO::try_create(uid_t uid)
|
||||||
{
|
{
|
||||||
return adopt_ref(*new FIFO(uid));
|
auto buffer = DoubleBuffer::try_create();
|
||||||
|
if (buffer)
|
||||||
|
return adopt_ref_if_nonnull(new (nothrow) FIFO(uid, buffer.release_nonnull()));
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
KResultOr<NonnullRefPtr<FileDescription>> FIFO::open_direction(FIFO::Direction direction)
|
KResultOr<NonnullRefPtr<FileDescription>> FIFO::open_direction(FIFO::Direction direction)
|
||||||
|
@ -70,15 +73,16 @@ KResultOr<NonnullRefPtr<FileDescription>> FIFO::open_direction_blocking(FIFO::Di
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
FIFO::FIFO(uid_t uid)
|
FIFO::FIFO(uid_t uid, NonnullOwnPtr<DoubleBuffer> buffer)
|
||||||
: m_uid(uid)
|
: m_buffer(move(buffer))
|
||||||
|
, m_uid(uid)
|
||||||
{
|
{
|
||||||
MutexLocker locker(all_fifos().lock());
|
MutexLocker locker(all_fifos().lock());
|
||||||
all_fifos().resource().set(this);
|
all_fifos().resource().set(this);
|
||||||
m_fifo_id = ++s_next_fifo_id;
|
m_fifo_id = ++s_next_fifo_id;
|
||||||
|
|
||||||
// Use the same block condition for read and write
|
// Use the same block condition for read and write
|
||||||
m_buffer.set_unblock_callback([this]() {
|
m_buffer->set_unblock_callback([this]() {
|
||||||
evaluate_block_conditions();
|
evaluate_block_conditions();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -115,19 +119,19 @@ void FIFO::detach(Direction direction)
|
||||||
|
|
||||||
bool FIFO::can_read(const FileDescription&, size_t) const
|
bool FIFO::can_read(const FileDescription&, size_t) const
|
||||||
{
|
{
|
||||||
return !m_buffer.is_empty() || !m_writers;
|
return !m_buffer->is_empty() || !m_writers;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FIFO::can_write(const FileDescription&, size_t) const
|
bool FIFO::can_write(const FileDescription&, size_t) const
|
||||||
{
|
{
|
||||||
return m_buffer.space_for_writing() || !m_readers;
|
return m_buffer->space_for_writing() || !m_readers;
|
||||||
}
|
}
|
||||||
|
|
||||||
KResultOr<size_t> FIFO::read(FileDescription&, u64, UserOrKernelBuffer& buffer, size_t size)
|
KResultOr<size_t> FIFO::read(FileDescription&, u64, UserOrKernelBuffer& buffer, size_t size)
|
||||||
{
|
{
|
||||||
if (!m_writers && m_buffer.is_empty())
|
if (!m_writers && m_buffer->is_empty())
|
||||||
return 0;
|
return 0;
|
||||||
return m_buffer.read(buffer, size);
|
return m_buffer->read(buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
KResultOr<size_t> FIFO::write(FileDescription&, u64, const UserOrKernelBuffer& buffer, size_t size)
|
KResultOr<size_t> FIFO::write(FileDescription&, u64, const UserOrKernelBuffer& buffer, size_t size)
|
||||||
|
@ -137,7 +141,7 @@ KResultOr<size_t> FIFO::write(FileDescription&, u64, const UserOrKernelBuffer& b
|
||||||
return EPIPE;
|
return EPIPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_buffer.write(buffer, size);
|
return m_buffer->write(buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
String FIFO::absolute_path(const FileDescription&) const
|
String FIFO::absolute_path(const FileDescription&) const
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
Writer
|
Writer
|
||||||
};
|
};
|
||||||
|
|
||||||
static NonnullRefPtr<FIFO> create(uid_t);
|
static RefPtr<FIFO> try_create(uid_t);
|
||||||
virtual ~FIFO() override;
|
virtual ~FIFO() override;
|
||||||
|
|
||||||
uid_t uid() const { return m_uid; }
|
uid_t uid() const { return m_uid; }
|
||||||
|
@ -49,11 +49,11 @@ private:
|
||||||
virtual StringView class_name() const override { return "FIFO"; }
|
virtual StringView class_name() const override { return "FIFO"; }
|
||||||
virtual bool is_fifo() const override { return true; }
|
virtual bool is_fifo() const override { return true; }
|
||||||
|
|
||||||
explicit FIFO(uid_t);
|
explicit FIFO(uid_t, NonnullOwnPtr<DoubleBuffer> buffer);
|
||||||
|
|
||||||
unsigned m_writers { 0 };
|
unsigned m_writers { 0 };
|
||||||
unsigned m_readers { 0 };
|
unsigned m_readers { 0 };
|
||||||
DoubleBuffer m_buffer;
|
NonnullOwnPtr<DoubleBuffer> m_buffer;
|
||||||
|
|
||||||
uid_t m_uid { 0 };
|
uid_t m_uid { 0 };
|
||||||
|
|
||||||
|
|
|
@ -185,8 +185,11 @@ NonnullRefPtr<FIFO> Inode::fifo()
|
||||||
VERIFY(metadata().is_fifo());
|
VERIFY(metadata().is_fifo());
|
||||||
|
|
||||||
// FIXME: Release m_fifo when it is closed by all readers and writers
|
// FIXME: Release m_fifo when it is closed by all readers and writers
|
||||||
if (!m_fifo)
|
if (!m_fifo) {
|
||||||
m_fifo = FIFO::create(metadata().uid);
|
m_fifo = FIFO::try_create(metadata().uid);
|
||||||
|
// FIXME: We need to be able to observe OOM here.
|
||||||
|
VERIFY(!m_fifo.is_null());
|
||||||
|
}
|
||||||
|
|
||||||
VERIFY(m_fifo);
|
VERIFY(m_fifo);
|
||||||
return *m_fifo;
|
return *m_fifo;
|
||||||
|
|
|
@ -20,7 +20,9 @@ KResultOr<FlatPtr> Process::sys$pipe(int pipefd[2], int flags)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
u32 fd_flags = (flags & O_CLOEXEC) ? FD_CLOEXEC : 0;
|
u32 fd_flags = (flags & O_CLOEXEC) ? FD_CLOEXEC : 0;
|
||||||
auto fifo = FIFO::create(uid());
|
auto fifo = FIFO::try_create(uid());
|
||||||
|
if (!fifo)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
auto open_reader_result = fifo->open_direction(FIFO::Direction::Reader);
|
auto open_reader_result = fifo->open_direction(FIFO::Direction::Reader);
|
||||||
if (open_reader_result.is_error())
|
if (open_reader_result.is_error())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue