summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-01-15 09:17:22 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-01-15 09:17:22 +0100
commite452303c664c3facfebe39539da0d796029bc603 (patch)
tree3e2ac04f858d480843606b3000cc4e5e7ac57c09
parent49b63281a09b61ab608f51a771f124f14c1ee1ad (diff)
downloadserenity-e452303c664c3facfebe39539da0d796029bc603.zip
Allow character devices to block write attempts until there is more space.
-rw-r--r--Kernel/Console.h1
-rw-r--r--Kernel/DoubleBuffer.h2
-rw-r--r--Kernel/FIFO.cpp2
-rw-r--r--Kernel/Keyboard.h1
-rw-r--r--Kernel/MasterPTY.cpp5
-rw-r--r--Kernel/MasterPTY.h1
-rw-r--r--Kernel/PS2MouseDevice.h1
-rw-r--r--Kernel/Process.cpp2
-rw-r--r--Kernel/Scheduler.cpp2
-rw-r--r--Kernel/SlavePTY.cpp5
-rw-r--r--Kernel/SlavePTY.h1
-rw-r--r--Kernel/TTY.cpp5
-rw-r--r--Kernel/TTY.h1
-rw-r--r--VirtualFileSystem/CharacterDevice.h1
-rw-r--r--VirtualFileSystem/FileDescriptor.cpp4
-rw-r--r--VirtualFileSystem/FileDescriptor.h2
-rw-r--r--VirtualFileSystem/FullDevice.h3
-rw-r--r--VirtualFileSystem/NullDevice.h1
-rw-r--r--VirtualFileSystem/RandomDevice.h1
-rw-r--r--VirtualFileSystem/ZeroDevice.h1
-rw-r--r--Widgets/GUIEventDevice.h4
21 files changed, 39 insertions, 7 deletions
diff --git a/Kernel/Console.h b/Kernel/Console.h
index 3568592884..7713e97d5b 100644
--- a/Kernel/Console.h
+++ b/Kernel/Console.h
@@ -19,6 +19,7 @@ public:
virtual ~Console() override;
virtual bool has_data_available_for_reading(Process&) const override;
+ virtual bool can_write(Process&) const override { return true; }
virtual ssize_t read(byte* buffer, size_t size) override;
virtual ssize_t write(const byte* data, size_t size) override;
diff --git a/Kernel/DoubleBuffer.h b/Kernel/DoubleBuffer.h
index b14b9431ce..206be8aec3 100644
--- a/Kernel/DoubleBuffer.h
+++ b/Kernel/DoubleBuffer.h
@@ -16,6 +16,8 @@ public:
bool is_empty() const { return m_read_buffer_index >= m_read_buffer->size() && m_write_buffer->is_empty(); }
+ size_t bytes_in_write_buffer() const { return m_write_buffer->size(); }
+
private:
void flip();
diff --git a/Kernel/FIFO.cpp b/Kernel/FIFO.cpp
index 9b65dc132b..2fbe23286c 100644
--- a/Kernel/FIFO.cpp
+++ b/Kernel/FIFO.cpp
@@ -51,7 +51,7 @@ bool FIFO::can_read() const
bool FIFO::can_write() const
{
- return true;
+ return m_buffer.bytes_in_write_buffer() < 4096;
}
ssize_t FIFO::read(byte* buffer, size_t size)
diff --git a/Kernel/Keyboard.h b/Kernel/Keyboard.h
index 9ebb096dbc..1de18601ad 100644
--- a/Kernel/Keyboard.h
+++ b/Kernel/Keyboard.h
@@ -40,6 +40,7 @@ private:
virtual ssize_t read(byte* buffer, size_t) override;
virtual ssize_t write(const byte* buffer, size_t) override;
virtual bool has_data_available_for_reading(Process&) const override;
+ virtual bool can_write(Process&) const override { return true; }
void emit(byte);
diff --git a/Kernel/MasterPTY.cpp b/Kernel/MasterPTY.cpp
index 2894839bc1..13eb54ace6 100644
--- a/Kernel/MasterPTY.cpp
+++ b/Kernel/MasterPTY.cpp
@@ -36,6 +36,11 @@ bool MasterPTY::has_data_available_for_reading(Process&) const
return !m_buffer.is_empty();
}
+bool MasterPTY::can_write(Process&) const
+{
+ return m_buffer.bytes_in_write_buffer() < 4096;
+}
+
void MasterPTY::on_slave_write(const byte* data, size_t size)
{
m_buffer.write(data, size);
diff --git a/Kernel/MasterPTY.h b/Kernel/MasterPTY.h
index 5876402680..4b4a60ed96 100644
--- a/Kernel/MasterPTY.h
+++ b/Kernel/MasterPTY.h
@@ -14,6 +14,7 @@ public:
virtual ssize_t read(byte*, size_t) override;
virtual ssize_t write(const byte*, size_t) override;
virtual bool has_data_available_for_reading(Process&) const override;
+ virtual bool can_write(Process&) const override;
virtual bool is_master_pty() const override { return true; }
String pts_name() const;
diff --git a/Kernel/PS2MouseDevice.h b/Kernel/PS2MouseDevice.h
index 89e3ce542a..eaeeaf7a7f 100644
--- a/Kernel/PS2MouseDevice.h
+++ b/Kernel/PS2MouseDevice.h
@@ -15,6 +15,7 @@ public:
virtual bool has_data_available_for_reading(Process&) const override;
virtual ssize_t read(byte* buffer, size_t) override;
virtual ssize_t write(const byte* buffer, size_t) override;
+ virtual bool can_write(Process&) const override { return true; }
private:
// ^IRQHandler
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index e6accc4761..b277501c3e 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -1023,7 +1023,7 @@ ssize_t Process::sys$write(int fd, const void* data, size_t size)
#ifdef IO_DEBUG
dbgprintf("while %u < %u\n", nwritten, size);
#endif
- if (!descriptor->can_write()) {
+ if (!descriptor->can_write(*this)) {
#ifdef IO_DEBUG
dbgprintf("block write on %d\n", fd);
#endif
diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp
index cd797cb722..4c99f6548e 100644
--- a/Kernel/Scheduler.cpp
+++ b/Kernel/Scheduler.cpp
@@ -59,7 +59,7 @@ bool Scheduler::pick_next()
if (process.state() == Process::BlockedWrite) {
ASSERT(process.m_blocked_fd != -1);
- if (process.m_fds[process.m_blocked_fd].descriptor->can_write())
+ if (process.m_fds[process.m_blocked_fd].descriptor->can_write(process))
process.unblock();
return true;
}
diff --git a/Kernel/SlavePTY.cpp b/Kernel/SlavePTY.cpp
index a693a8ce58..3c0898e28b 100644
--- a/Kernel/SlavePTY.cpp
+++ b/Kernel/SlavePTY.cpp
@@ -29,3 +29,8 @@ void SlavePTY::on_tty_write(const byte* data, size_t size)
{
m_master->on_slave_write(data, size);
}
+
+bool SlavePTY::can_write(Process& process) const
+{
+ return m_master->can_write(process);
+}
diff --git a/Kernel/SlavePTY.h b/Kernel/SlavePTY.h
index 34601e0b14..312efa740b 100644
--- a/Kernel/SlavePTY.h
+++ b/Kernel/SlavePTY.h
@@ -16,6 +16,7 @@ public:
protected:
virtual void on_tty_write(const byte*, size_t) override;
+ virtual bool can_write(Process&) const override;
private:
unsigned m_index;
diff --git a/Kernel/TTY.cpp b/Kernel/TTY.cpp
index 75941250be..4aca0f0e1a 100644
--- a/Kernel/TTY.cpp
+++ b/Kernel/TTY.cpp
@@ -47,6 +47,11 @@ bool TTY::has_data_available_for_reading(Process&) const
return !m_buffer.is_empty();
}
+bool TTY::can_write(Process&) const
+{
+ return true;
+}
+
void TTY::emit(byte ch)
{
if (should_generate_signals()) {
diff --git a/Kernel/TTY.h b/Kernel/TTY.h
index 8d92f89391..b739d55e17 100644
--- a/Kernel/TTY.h
+++ b/Kernel/TTY.h
@@ -13,6 +13,7 @@ public:
virtual ssize_t read(byte*, size_t) override;
virtual ssize_t write(const byte*, size_t) override;
virtual bool has_data_available_for_reading(Process&) const override;
+ virtual bool can_write(Process&) const override;
virtual int ioctl(Process&, unsigned request, unsigned arg) override final;
virtual String tty_name() const = 0;
diff --git a/VirtualFileSystem/CharacterDevice.h b/VirtualFileSystem/CharacterDevice.h
index 6812a22e6e..d203b9f8b6 100644
--- a/VirtualFileSystem/CharacterDevice.h
+++ b/VirtualFileSystem/CharacterDevice.h
@@ -13,6 +13,7 @@ public:
RetainPtr<FileDescriptor> open(int options);
virtual bool has_data_available_for_reading(Process&) const = 0;
+ virtual bool can_write(Process&) const = 0;
virtual ssize_t read(byte* buffer, size_t bufferSize) = 0;
virtual ssize_t write(const byte* buffer, size_t bufferSize) = 0;
diff --git a/VirtualFileSystem/FileDescriptor.cpp b/VirtualFileSystem/FileDescriptor.cpp
index 32a13af2cd..f4a87eb948 100644
--- a/VirtualFileSystem/FileDescriptor.cpp
+++ b/VirtualFileSystem/FileDescriptor.cpp
@@ -165,12 +165,14 @@ ssize_t FileDescriptor::write(const byte* data, size_t size)
return -1;
}
-bool FileDescriptor::can_write()
+bool FileDescriptor::can_write(Process& process)
{
if (is_fifo()) {
ASSERT(fifo_direction() == FIFO::Writer);
return m_fifo->can_write();
}
+ if (m_vnode->isCharacterDevice())
+ return m_vnode->characterDevice()->can_write(process);
return true;
}
diff --git a/VirtualFileSystem/FileDescriptor.h b/VirtualFileSystem/FileDescriptor.h
index 2441f18913..6fe5cdb32b 100644
--- a/VirtualFileSystem/FileDescriptor.h
+++ b/VirtualFileSystem/FileDescriptor.h
@@ -30,7 +30,7 @@ public:
int stat(Unix::stat*);
bool has_data_available_for_reading(Process&);
- bool can_write();
+ bool can_write(Process&);
ssize_t get_dir_entries(byte* buffer, size_t);
diff --git a/VirtualFileSystem/FullDevice.h b/VirtualFileSystem/FullDevice.h
index f75c5a6edf..2f769f64bb 100644
--- a/VirtualFileSystem/FullDevice.h
+++ b/VirtualFileSystem/FullDevice.h
@@ -6,10 +6,11 @@ class FullDevice final : public CharacterDevice {
AK_MAKE_ETERNAL
public:
FullDevice();
- virtual ~FullDevice();
+ virtual ~FullDevice() override;
virtual ssize_t read(byte* buffer, size_t bufferSize) override;
virtual ssize_t write(const byte* buffer, size_t bufferSize) override;
virtual bool has_data_available_for_reading(Process&) const override;
+ virtual bool can_write(Process&) const override { return true; }
};
diff --git a/VirtualFileSystem/NullDevice.h b/VirtualFileSystem/NullDevice.h
index c73f35a9bb..b9abfa3019 100644
--- a/VirtualFileSystem/NullDevice.h
+++ b/VirtualFileSystem/NullDevice.h
@@ -10,6 +10,7 @@ public:
virtual ssize_t read(byte* buffer, size_t bufferSize) override;
virtual ssize_t write(const byte* buffer, size_t bufferSize) override;
+ virtual bool can_write(Process&) const override { return true; }
virtual bool has_data_available_for_reading(Process&) const override;
};
diff --git a/VirtualFileSystem/RandomDevice.h b/VirtualFileSystem/RandomDevice.h
index 4d7436dacb..9299ddcc15 100644
--- a/VirtualFileSystem/RandomDevice.h
+++ b/VirtualFileSystem/RandomDevice.h
@@ -11,5 +11,6 @@ public:
virtual ssize_t read(byte* buffer, size_t bufferSize) override;
virtual ssize_t write(const byte* buffer, size_t bufferSize) override;
virtual bool has_data_available_for_reading(Process&) const override;
+ virtual bool can_write(Process&) const override { return true; }
};
diff --git a/VirtualFileSystem/ZeroDevice.h b/VirtualFileSystem/ZeroDevice.h
index 9bc64b6908..8ed62549ca 100644
--- a/VirtualFileSystem/ZeroDevice.h
+++ b/VirtualFileSystem/ZeroDevice.h
@@ -11,5 +11,6 @@ public:
virtual ssize_t read(byte* buffer, size_t bufferSize) override;
virtual ssize_t write(const byte* buffer, size_t bufferSize) override;
virtual bool has_data_available_for_reading(Process&) const override;
+ virtual bool can_write(Process&) const override { return true; }
};
diff --git a/Widgets/GUIEventDevice.h b/Widgets/GUIEventDevice.h
index 061fc96e71..a21cfc6769 100644
--- a/Widgets/GUIEventDevice.h
+++ b/Widgets/GUIEventDevice.h
@@ -8,7 +8,9 @@ public:
virtual ~GUIEventDevice() override;
private:
- virtual bool has_data_available_for_reading(Process&) const override;
+ // ^CharacterDevice
virtual ssize_t read(byte* buffer, size_t bufferSize) override;
virtual ssize_t write(const byte* buffer, size_t bufferSize) override;
+ virtual bool has_data_available_for_reading(Process&) const override;
+ virtual bool can_write(Process&) const override { return true; }
};