mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:47:44 +00:00
Kernel+LibC: Implement sigtimedwait()
This includes a new Thread::Blocker called SignalBlocker which blocks until a signal of a matching type is pending. The current Blocker implementation in the Kernel is very complicated, but cleaning it up is a different yak for a different day.
This commit is contained in:
parent
13d98999b7
commit
762e047ec9
8 changed files with 120 additions and 0 deletions
|
@ -292,6 +292,7 @@ public:
|
|||
Queue,
|
||||
Routing,
|
||||
Sleep,
|
||||
Signal,
|
||||
Wait
|
||||
};
|
||||
virtual ~Blocker();
|
||||
|
@ -698,6 +699,41 @@ public:
|
|||
bool m_did_unblock { false };
|
||||
};
|
||||
|
||||
class SignalBlocker final : public Blocker {
|
||||
public:
|
||||
explicit SignalBlocker(sigset_t pending_set, siginfo_t& result);
|
||||
virtual StringView state_string() const override { return "Pending Signal"sv; }
|
||||
virtual Type blocker_type() const override { return Type::Signal; }
|
||||
void will_unblock_immediately_without_blocking(UnblockImmediatelyReason) override;
|
||||
virtual bool setup_blocker() override;
|
||||
bool check_pending_signals(bool from_add_blocker);
|
||||
|
||||
private:
|
||||
sigset_t m_pending_set { 0 };
|
||||
siginfo_t& m_result;
|
||||
bool m_did_unblock { false };
|
||||
};
|
||||
|
||||
class SignalBlockerSet final : public BlockerSet {
|
||||
public:
|
||||
void unblock_all_blockers_whose_conditions_are_met()
|
||||
{
|
||||
BlockerSet::unblock_all_blockers_whose_conditions_are_met([&](auto& b, void*, bool&) {
|
||||
VERIFY(b.blocker_type() == Blocker::Type::Signal);
|
||||
auto& blocker = static_cast<Thread::SignalBlocker&>(b);
|
||||
return blocker.check_pending_signals(false);
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
bool should_add_blocker(Blocker& b, void*) override
|
||||
{
|
||||
VERIFY(b.blocker_type() == Blocker::Type::Signal);
|
||||
auto& blocker = static_cast<Thread::SignalBlocker&>(b);
|
||||
return !blocker.check_pending_signals(true);
|
||||
}
|
||||
};
|
||||
|
||||
class WaitBlocker final : public Blocker {
|
||||
public:
|
||||
enum class UnblockFlags {
|
||||
|
@ -1302,6 +1338,7 @@ private:
|
|||
u32 m_signal_mask { 0 };
|
||||
FlatPtr m_alternative_signal_stack { 0 };
|
||||
FlatPtr m_alternative_signal_stack_size { 0 };
|
||||
SignalBlockerSet m_signal_blocker_set;
|
||||
FlatPtr m_kernel_stack_base { 0 };
|
||||
FlatPtr m_kernel_stack_top { 0 };
|
||||
OwnPtr<Memory::Region> m_kernel_stack_region;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue