mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 13:57:35 +00:00
Kernel: Some small refinements to the thread blockers.
Committing some things my hands did while browsing through this code. - Mark all leaf classes "final". - FileDescriptionBlocker now stores a NonnullRefPtr<FileDescription>. - FileDescriptionBlocker::blocked_description() now returns a reference. - ConditionBlocker takes a Function&&.
This commit is contained in:
parent
80a6df9022
commit
705cd2491c
5 changed files with 49 additions and 54 deletions
|
@ -143,14 +143,16 @@ ssize_t FileDescription::write(const u8* data, ssize_t size)
|
||||||
return nwritten;
|
return nwritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileDescription::can_write()
|
bool FileDescription::can_write() const
|
||||||
{
|
{
|
||||||
return m_file->can_write(*this);
|
// FIXME: Remove this const_cast.
|
||||||
|
return m_file->can_write(const_cast<FileDescription&>(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileDescription::can_read()
|
bool FileDescription::can_read() const
|
||||||
{
|
{
|
||||||
return m_file->can_read(*this);
|
// FIXME: Remove this const_cast.
|
||||||
|
return m_file->can_read(const_cast<FileDescription&>(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer FileDescription::read_entire_file()
|
ByteBuffer FileDescription::read_entire_file()
|
||||||
|
|
|
@ -36,8 +36,8 @@ public:
|
||||||
|
|
||||||
KResult fchmod(mode_t);
|
KResult fchmod(mode_t);
|
||||||
|
|
||||||
bool can_read();
|
bool can_read() const;
|
||||||
bool can_write();
|
bool can_write() const;
|
||||||
|
|
||||||
ssize_t get_dir_entries(u8* buffer, ssize_t);
|
ssize_t get_dir_entries(u8* buffer, ssize_t);
|
||||||
|
|
||||||
|
|
|
@ -51,67 +51,63 @@ void Scheduler::beep()
|
||||||
s_beep_timeout = g_uptime + 100;
|
s_beep_timeout = g_uptime + 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::FileDescriptionBlocker::FileDescriptionBlocker(const RefPtr<FileDescription>& description)
|
Thread::FileDescriptionBlocker::FileDescriptionBlocker(const FileDescription& description)
|
||||||
: m_blocked_description(description)
|
: m_blocked_description(description)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
RefPtr<FileDescription> Thread::FileDescriptionBlocker::blocked_description() const
|
const FileDescription& Thread::FileDescriptionBlocker::blocked_description() const
|
||||||
{
|
{
|
||||||
return m_blocked_description;
|
return m_blocked_description;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::AcceptBlocker::AcceptBlocker(const RefPtr<FileDescription>& description)
|
Thread::AcceptBlocker::AcceptBlocker(const FileDescription& description)
|
||||||
: FileDescriptionBlocker(description)
|
: FileDescriptionBlocker(description)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Thread::AcceptBlocker::should_unblock(Thread&, time_t, long)
|
bool Thread::AcceptBlocker::should_unblock(Thread&, time_t, long)
|
||||||
{
|
{
|
||||||
auto& description = *blocked_description();
|
auto& socket = *blocked_description().socket();
|
||||||
auto& socket = *description.socket();
|
|
||||||
|
|
||||||
return socket.can_accept();
|
return socket.can_accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::ReceiveBlocker::ReceiveBlocker(const RefPtr<FileDescription>& description)
|
Thread::ReceiveBlocker::ReceiveBlocker(const FileDescription& description)
|
||||||
: FileDescriptionBlocker(description)
|
: FileDescriptionBlocker(description)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Thread::ReceiveBlocker::should_unblock(Thread&, time_t now_sec, long now_usec)
|
bool Thread::ReceiveBlocker::should_unblock(Thread&, time_t now_sec, long now_usec)
|
||||||
{
|
{
|
||||||
auto& description = *blocked_description();
|
auto& socket = *blocked_description().socket();
|
||||||
auto& socket = *description.socket();
|
|
||||||
// FIXME: Block until the amount of data wanted is available.
|
// FIXME: Block until the amount of data wanted is available.
|
||||||
bool timed_out = now_sec > socket.receive_deadline().tv_sec || (now_sec == socket.receive_deadline().tv_sec && now_usec >= socket.receive_deadline().tv_usec);
|
bool timed_out = now_sec > socket.receive_deadline().tv_sec || (now_sec == socket.receive_deadline().tv_sec && now_usec >= socket.receive_deadline().tv_usec);
|
||||||
if (timed_out || description.can_read())
|
if (timed_out || blocked_description().can_read())
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::ConnectBlocker::ConnectBlocker(const RefPtr<FileDescription>& description)
|
Thread::ConnectBlocker::ConnectBlocker(const FileDescription& description)
|
||||||
: FileDescriptionBlocker(description)
|
: FileDescriptionBlocker(description)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Thread::ConnectBlocker::should_unblock(Thread&, time_t, long)
|
bool Thread::ConnectBlocker::should_unblock(Thread&, time_t, long)
|
||||||
{
|
{
|
||||||
auto& description = *blocked_description();
|
auto& socket = *blocked_description().socket();
|
||||||
auto& socket = *description.socket();
|
|
||||||
return socket.is_connected();
|
return socket.is_connected();
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::WriteBlocker::WriteBlocker(const RefPtr<FileDescription>& description)
|
Thread::WriteBlocker::WriteBlocker(const FileDescription& description)
|
||||||
: FileDescriptionBlocker(description)
|
: FileDescriptionBlocker(description)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Thread::WriteBlocker::should_unblock(Thread&, time_t, long)
|
bool Thread::WriteBlocker::should_unblock(Thread&, time_t, long)
|
||||||
{
|
{
|
||||||
return blocked_description()->can_write();
|
return blocked_description().can_write();
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::ReadBlocker::ReadBlocker(const RefPtr<FileDescription>& description)
|
Thread::ReadBlocker::ReadBlocker(const FileDescription& description)
|
||||||
: FileDescriptionBlocker(description)
|
: FileDescriptionBlocker(description)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -119,10 +115,10 @@ Thread::ReadBlocker::ReadBlocker(const RefPtr<FileDescription>& description)
|
||||||
bool Thread::ReadBlocker::should_unblock(Thread&, time_t, long)
|
bool Thread::ReadBlocker::should_unblock(Thread&, time_t, long)
|
||||||
{
|
{
|
||||||
// FIXME: Block until the amount of data wanted is available.
|
// FIXME: Block until the amount of data wanted is available.
|
||||||
return blocked_description()->can_read();
|
return blocked_description().can_read();
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::ConditionBlocker::ConditionBlocker(const char* state_string, Function<bool()> &condition)
|
Thread::ConditionBlocker::ConditionBlocker(const char* state_string, Function<bool()>&& condition)
|
||||||
: m_block_until_condition(move(condition))
|
: m_block_until_condition(move(condition))
|
||||||
, m_state_string(state_string)
|
, m_state_string(state_string)
|
||||||
{
|
{
|
||||||
|
|
|
@ -110,7 +110,7 @@ void Thread::unblock()
|
||||||
|
|
||||||
void Thread::block_until(const char* state_string, Function<bool()>&& condition)
|
void Thread::block_until(const char* state_string, Function<bool()>&& condition)
|
||||||
{
|
{
|
||||||
block<ConditionBlocker>(state_string, condition);
|
block<ConditionBlocker>(state_string, move(condition));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::block_helper()
|
void Thread::block_helper()
|
||||||
|
|
|
@ -75,62 +75,62 @@ public:
|
||||||
|
|
||||||
class FileDescriptionBlocker : public Blocker {
|
class FileDescriptionBlocker : public Blocker {
|
||||||
public:
|
public:
|
||||||
FileDescriptionBlocker(const RefPtr<FileDescription>& description);
|
explicit FileDescriptionBlocker(const FileDescription&);
|
||||||
RefPtr<FileDescription> blocked_description() const;
|
const FileDescription& blocked_description() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RefPtr<FileDescription> m_blocked_description;
|
NonnullRefPtr<FileDescription> m_blocked_description;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AcceptBlocker : public FileDescriptionBlocker {
|
class AcceptBlocker final : public FileDescriptionBlocker {
|
||||||
public:
|
public:
|
||||||
AcceptBlocker(const RefPtr<FileDescription>& description);
|
explicit AcceptBlocker(const FileDescription&);
|
||||||
virtual bool should_unblock(Thread&, time_t, long) override;
|
virtual bool should_unblock(Thread&, time_t, long) override;
|
||||||
virtual const char* state_string() const override { return "Accepting"; }
|
virtual const char* state_string() const override { return "Accepting"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ReceiveBlocker : public FileDescriptionBlocker {
|
class ReceiveBlocker final : public FileDescriptionBlocker {
|
||||||
public:
|
public:
|
||||||
ReceiveBlocker(const RefPtr<FileDescription>& description);
|
explicit ReceiveBlocker(const FileDescription&);
|
||||||
virtual bool should_unblock(Thread&, time_t, long) override;
|
virtual bool should_unblock(Thread&, time_t, long) override;
|
||||||
virtual const char* state_string() const override { return "Receiving"; }
|
virtual const char* state_string() const override { return "Receiving"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConnectBlocker : public FileDescriptionBlocker {
|
class ConnectBlocker final : public FileDescriptionBlocker {
|
||||||
public:
|
public:
|
||||||
ConnectBlocker(const RefPtr<FileDescription>& description);
|
explicit ConnectBlocker(const FileDescription&);
|
||||||
virtual bool should_unblock(Thread&, time_t, long) override;
|
virtual bool should_unblock(Thread&, time_t, long) override;
|
||||||
virtual const char* state_string() const override { return "Connecting"; }
|
virtual const char* state_string() const override { return "Connecting"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class WriteBlocker : public FileDescriptionBlocker {
|
class WriteBlocker final : public FileDescriptionBlocker {
|
||||||
public:
|
public:
|
||||||
WriteBlocker(const RefPtr<FileDescription>& description);
|
explicit WriteBlocker(const FileDescription&);
|
||||||
virtual bool should_unblock(Thread&, time_t, long) override;
|
virtual bool should_unblock(Thread&, time_t, long) override;
|
||||||
virtual const char* state_string() const override { return "Writing"; }
|
virtual const char* state_string() const override { return "Writing"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ReadBlocker : public FileDescriptionBlocker {
|
class ReadBlocker final : public FileDescriptionBlocker {
|
||||||
public:
|
public:
|
||||||
ReadBlocker(const RefPtr<FileDescription>& description);
|
explicit ReadBlocker(const FileDescription&);
|
||||||
virtual bool should_unblock(Thread&, time_t, long) override;
|
virtual bool should_unblock(Thread&, time_t, long) override;
|
||||||
virtual const char* state_string() const override { return "Reading"; }
|
virtual const char* state_string() const override { return "Reading"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConditionBlocker : public Blocker {
|
class ConditionBlocker final : public Blocker {
|
||||||
public:
|
public:
|
||||||
ConditionBlocker(const char* state_string, Function<bool()> &condition);
|
ConditionBlocker(const char* state_string, Function<bool()>&& condition);
|
||||||
virtual bool should_unblock(Thread&, time_t, long) override;
|
virtual bool should_unblock(Thread&, time_t, long) override;
|
||||||
virtual const char* state_string() const override { return m_state_string; }
|
virtual const char* state_string() const override { return m_state_string; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Function<bool()> m_block_until_condition;
|
Function<bool()> m_block_until_condition;
|
||||||
const char* m_state_string;
|
const char* m_state_string { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
class SleepBlocker : public Blocker {
|
class SleepBlocker final : public Blocker {
|
||||||
public:
|
public:
|
||||||
SleepBlocker(u64 wakeup_time);
|
explicit SleepBlocker(u64 wakeup_time);
|
||||||
virtual bool should_unblock(Thread&, time_t, long) override;
|
virtual bool should_unblock(Thread&, time_t, long) override;
|
||||||
virtual const char* state_string() const override { return "Sleeping"; }
|
virtual const char* state_string() const override { return "Sleeping"; }
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ public:
|
||||||
u64 m_wakeup_time { 0 };
|
u64 m_wakeup_time { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
class SelectBlocker : public Blocker {
|
class SelectBlocker final : public Blocker {
|
||||||
public:
|
public:
|
||||||
typedef Vector<int, FD_SETSIZE> FDVector;
|
typedef Vector<int, FD_SETSIZE> FDVector;
|
||||||
SelectBlocker(const timeval& tv, bool select_has_timeout, const FDVector& read_fds, const FDVector& write_fds, const FDVector& except_fds);
|
SelectBlocker(const timeval& tv, bool select_has_timeout, const FDVector& read_fds, const FDVector& write_fds, const FDVector& except_fds);
|
||||||
|
@ -153,7 +153,7 @@ public:
|
||||||
const FDVector& m_select_exceptional_fds;
|
const FDVector& m_select_exceptional_fds;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WaitBlocker : public Blocker {
|
class WaitBlocker final : public Blocker {
|
||||||
public:
|
public:
|
||||||
WaitBlocker(int wait_options, pid_t& waitee_pid);
|
WaitBlocker(int wait_options, pid_t& waitee_pid);
|
||||||
virtual bool should_unblock(Thread&, time_t, long) override;
|
virtual bool should_unblock(Thread&, time_t, long) override;
|
||||||
|
@ -164,7 +164,7 @@ public:
|
||||||
pid_t& m_waitee_pid;
|
pid_t& m_waitee_pid;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SemiPermanentBlocker : public Blocker {
|
class SemiPermanentBlocker final : public Blocker {
|
||||||
public:
|
public:
|
||||||
enum class Reason {
|
enum class Reason {
|
||||||
Lurking,
|
Lurking,
|
||||||
|
@ -176,10 +176,10 @@ public:
|
||||||
virtual const char* state_string() const override
|
virtual const char* state_string() const override
|
||||||
{
|
{
|
||||||
switch (m_reason) {
|
switch (m_reason) {
|
||||||
case Reason::Lurking:
|
case Reason::Lurking:
|
||||||
return "Lurking";
|
return "Lurking";
|
||||||
case Reason::Signal:
|
case Reason::Signal:
|
||||||
return "Signal";
|
return "Signal";
|
||||||
}
|
}
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
@ -192,10 +192,7 @@ public:
|
||||||
u32 times_scheduled() const { return m_times_scheduled; }
|
u32 times_scheduled() const { return m_times_scheduled; }
|
||||||
|
|
||||||
bool is_stopped() const { return m_state == Stopped; }
|
bool is_stopped() const { return m_state == Stopped; }
|
||||||
bool is_blocked() const
|
bool is_blocked() const { return m_state == Blocked; }
|
||||||
{
|
|
||||||
return m_state == Blocked;
|
|
||||||
}
|
|
||||||
bool in_kernel() const { return (m_tss.cs & 0x03) == 0; }
|
bool in_kernel() const { return (m_tss.cs & 0x03) == 0; }
|
||||||
|
|
||||||
u32 frame_ptr() const { return m_tss.ebp; }
|
u32 frame_ptr() const { return m_tss.ebp; }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue