diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-01-15 09:17:22 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-01-15 09:17:22 +0100 |
commit | e452303c664c3facfebe39539da0d796029bc603 (patch) | |
tree | 3e2ac04f858d480843606b3000cc4e5e7ac57c09 | |
parent | 49b63281a09b61ab608f51a771f124f14c1ee1ad (diff) | |
download | serenity-e452303c664c3facfebe39539da0d796029bc603.zip |
Allow character devices to block write attempts until there is more space.
-rw-r--r-- | Kernel/Console.h | 1 | ||||
-rw-r--r-- | Kernel/DoubleBuffer.h | 2 | ||||
-rw-r--r-- | Kernel/FIFO.cpp | 2 | ||||
-rw-r--r-- | Kernel/Keyboard.h | 1 | ||||
-rw-r--r-- | Kernel/MasterPTY.cpp | 5 | ||||
-rw-r--r-- | Kernel/MasterPTY.h | 1 | ||||
-rw-r--r-- | Kernel/PS2MouseDevice.h | 1 | ||||
-rw-r--r-- | Kernel/Process.cpp | 2 | ||||
-rw-r--r-- | Kernel/Scheduler.cpp | 2 | ||||
-rw-r--r-- | Kernel/SlavePTY.cpp | 5 | ||||
-rw-r--r-- | Kernel/SlavePTY.h | 1 | ||||
-rw-r--r-- | Kernel/TTY.cpp | 5 | ||||
-rw-r--r-- | Kernel/TTY.h | 1 | ||||
-rw-r--r-- | VirtualFileSystem/CharacterDevice.h | 1 | ||||
-rw-r--r-- | VirtualFileSystem/FileDescriptor.cpp | 4 | ||||
-rw-r--r-- | VirtualFileSystem/FileDescriptor.h | 2 | ||||
-rw-r--r-- | VirtualFileSystem/FullDevice.h | 3 | ||||
-rw-r--r-- | VirtualFileSystem/NullDevice.h | 1 | ||||
-rw-r--r-- | VirtualFileSystem/RandomDevice.h | 1 | ||||
-rw-r--r-- | VirtualFileSystem/ZeroDevice.h | 1 | ||||
-rw-r--r-- | Widgets/GUIEventDevice.h | 4 |
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; } }; |