mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 19:45:12 +00:00
Add a DoubleBuffer thingy to allow TTY read/write to be interleaved.
I feel like this concept might be useful in more places. It's very naive right now and uses dynamically growing buffers. It should really use static size buffers and never kmalloc().
This commit is contained in:
parent
52d1822c3c
commit
d2046e79cf
Notes:
sideshowbarker
2024-07-19 16:10:15 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/d2046e79cfd
3 changed files with 63 additions and 12 deletions
|
@ -188,6 +188,14 @@ public:
|
|||
++m_impl->m_size;
|
||||
}
|
||||
|
||||
void append(const T* values, size_t count)
|
||||
{
|
||||
ensureCapacity(size() + count);
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
new (m_impl->slot(m_impl->m_size + i)) T(values[i]);
|
||||
m_impl->m_size += count;
|
||||
}
|
||||
|
||||
void ensureCapacity(size_t neededCapacity)
|
||||
{
|
||||
if (capacity() >= neededCapacity)
|
||||
|
|
|
@ -4,6 +4,32 @@
|
|||
#include <LibC/signal_numbers.h>
|
||||
#include <LibC/sys/ioctl_numbers.h>
|
||||
|
||||
void DoubleBuffer::flip()
|
||||
{
|
||||
ASSERT(m_read_buffer_index == m_read_buffer->size());
|
||||
swap(m_read_buffer, m_write_buffer);
|
||||
m_write_buffer->clear();
|
||||
m_read_buffer_index = 0;
|
||||
}
|
||||
|
||||
Unix::ssize_t DoubleBuffer::write(const byte* data, size_t size)
|
||||
{
|
||||
m_write_buffer->append(data, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
Unix::ssize_t DoubleBuffer::read(byte* data, size_t size)
|
||||
{
|
||||
if (m_read_buffer_index >= m_read_buffer->size() && !m_write_buffer->isEmpty())
|
||||
flip();
|
||||
if (m_read_buffer_index >= m_read_buffer->size())
|
||||
return 0;
|
||||
ssize_t nread = min(m_read_buffer->size() - m_read_buffer_index, size);
|
||||
memcpy(data, m_read_buffer->data() + m_read_buffer_index, nread);
|
||||
m_read_buffer_index += nread;
|
||||
return nread;
|
||||
}
|
||||
|
||||
TTY::TTY(unsigned major, unsigned minor)
|
||||
: CharacterDevice(major, minor)
|
||||
{
|
||||
|
@ -17,15 +43,7 @@ TTY::~TTY()
|
|||
|
||||
ssize_t TTY::read(byte* buffer, size_t size)
|
||||
{
|
||||
ssize_t nread = min(m_buffer.size(), size);
|
||||
memcpy(buffer, m_buffer.data(), nread);
|
||||
if (nread == (ssize_t)m_buffer.size())
|
||||
m_buffer.clear();
|
||||
else {
|
||||
kprintf("had %u, read %u\n", m_buffer.size(), nread);
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
return nread;
|
||||
return m_buffer.read(buffer, size);
|
||||
}
|
||||
|
||||
ssize_t TTY::write(const byte* buffer, size_t size)
|
||||
|
@ -36,12 +54,12 @@ ssize_t TTY::write(const byte* buffer, size_t size)
|
|||
|
||||
bool TTY::hasDataAvailableForRead() const
|
||||
{
|
||||
return !m_buffer.isEmpty();
|
||||
return !m_buffer.is_empty();
|
||||
}
|
||||
|
||||
void TTY::emit(byte ch)
|
||||
{
|
||||
m_buffer.append(ch);
|
||||
m_buffer.write(&ch, 1);
|
||||
}
|
||||
|
||||
void TTY::interrupt()
|
||||
|
@ -93,6 +111,8 @@ int TTY::ioctl(Process& process, unsigned request, unsigned arg)
|
|||
*tp = m_termios;
|
||||
return 0;
|
||||
case TCSETS:
|
||||
case TCSETSF:
|
||||
case TCSETSW:
|
||||
tp = reinterpret_cast<Unix::termios*>(arg);
|
||||
if (!process.validate_read(tp, sizeof(Unix::termios)))
|
||||
return -EFAULT;
|
||||
|
|
25
Kernel/TTY.h
25
Kernel/TTY.h
|
@ -5,6 +5,29 @@
|
|||
|
||||
class Process;
|
||||
|
||||
class DoubleBuffer {
|
||||
public:
|
||||
DoubleBuffer()
|
||||
: m_write_buffer(&m_buffer1)
|
||||
, m_read_buffer(&m_buffer2)
|
||||
{
|
||||
}
|
||||
|
||||
Unix::ssize_t write(const byte*, size_t);
|
||||
Unix::ssize_t read(byte*, size_t);
|
||||
|
||||
bool is_empty() const { return m_read_buffer_index >= m_read_buffer->size() && m_write_buffer->isEmpty(); }
|
||||
|
||||
private:
|
||||
void flip();
|
||||
|
||||
Vector<byte>* m_write_buffer { nullptr };
|
||||
Vector<byte>* m_read_buffer { nullptr };
|
||||
Vector<byte> m_buffer1;
|
||||
Vector<byte> m_buffer2;
|
||||
size_t m_read_buffer_index { 0 };
|
||||
};
|
||||
|
||||
class TTY : public CharacterDevice {
|
||||
public:
|
||||
virtual ~TTY() override;
|
||||
|
@ -35,7 +58,7 @@ protected:
|
|||
void interrupt();
|
||||
|
||||
private:
|
||||
Vector<byte> m_buffer;
|
||||
DoubleBuffer m_buffer;
|
||||
pid_t m_pgid { 0 };
|
||||
Unix::termios m_termios;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue