mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 07:48:11 +00:00
Kernel: Rename Thread::BlockCondition to BlockerSet
This class represents a set of Thread::Blocker objects attached to something that those blockers are waiting on.
This commit is contained in:
parent
05e1b196e9
commit
85546af417
15 changed files with 83 additions and 86 deletions
|
@ -21,9 +21,9 @@ namespace Kernel {
|
||||||
|
|
||||||
class File;
|
class File;
|
||||||
|
|
||||||
class FileBlockCondition final : public Thread::BlockCondition {
|
class FileBlockerSet final : public Thread::BlockerSet {
|
||||||
public:
|
public:
|
||||||
FileBlockCondition() { }
|
FileBlockerSet() { }
|
||||||
|
|
||||||
virtual bool should_add_blocker(Thread::Blocker& b, void* data) override
|
virtual bool should_add_blocker(Thread::Blocker& b, void* data) override
|
||||||
{
|
{
|
||||||
|
@ -112,7 +112,7 @@ public:
|
||||||
virtual bool is_socket() const { return false; }
|
virtual bool is_socket() const { return false; }
|
||||||
virtual bool is_inode_watcher() const { return false; }
|
virtual bool is_inode_watcher() const { return false; }
|
||||||
|
|
||||||
virtual FileBlockCondition& block_condition() { return m_block_condition; }
|
virtual FileBlockerSet& blocker_set() { return m_blocker_set; }
|
||||||
|
|
||||||
size_t attach_count() const { return m_attach_count; }
|
size_t attach_count() const { return m_attach_count; }
|
||||||
|
|
||||||
|
@ -138,10 +138,10 @@ private:
|
||||||
ALWAYS_INLINE void do_evaluate_block_conditions()
|
ALWAYS_INLINE void do_evaluate_block_conditions()
|
||||||
{
|
{
|
||||||
VERIFY(!Processor::current_in_irq());
|
VERIFY(!Processor::current_in_irq());
|
||||||
block_condition().unblock();
|
blocker_set().unblock();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileBlockCondition m_block_condition;
|
FileBlockerSet m_blocker_set;
|
||||||
size_t m_attach_count { 0 };
|
size_t m_attach_count { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -443,9 +443,9 @@ KResult FileDescription::chown(uid_t uid, gid_t gid)
|
||||||
return m_file->chown(*this, uid, gid);
|
return m_file->chown(*this, uid, gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileBlockCondition& FileDescription::block_condition()
|
FileBlockerSet& FileDescription::blocker_set()
|
||||||
{
|
{
|
||||||
return m_file->block_condition();
|
return m_file->blocker_set();
|
||||||
}
|
}
|
||||||
|
|
||||||
KResult FileDescription::apply_flock(Process const& process, Userspace<flock const*> lock)
|
KResult FileDescription::apply_flock(Process const& process, Userspace<flock const*> lock)
|
||||||
|
|
|
@ -125,7 +125,7 @@ public:
|
||||||
|
|
||||||
KResult chown(uid_t, gid_t);
|
KResult chown(uid_t, gid_t);
|
||||||
|
|
||||||
FileBlockCondition& block_condition();
|
FileBlockerSet& blocker_set();
|
||||||
|
|
||||||
KResult apply_flock(Process const&, Userspace<flock const*>);
|
KResult apply_flock(Process const&, Userspace<flock const*>);
|
||||||
KResult get_flock(Userspace<flock*>) const;
|
KResult get_flock(Userspace<flock*>) const;
|
||||||
|
@ -138,7 +138,7 @@ private:
|
||||||
|
|
||||||
void evaluate_block_conditions()
|
void evaluate_block_conditions()
|
||||||
{
|
{
|
||||||
block_condition().unblock();
|
blocker_set().unblock();
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Custody> m_custody;
|
RefPtr<Custody> m_custody;
|
||||||
|
|
|
@ -442,14 +442,14 @@ bool Plan9FS::Blocker::is_completed() const
|
||||||
return m_completion->completed;
|
return m_completion->completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Plan9FS::Plan9FSBlockCondition::should_add_blocker(Thread::Blocker& b, void*)
|
bool Plan9FS::Plan9FSBlockerSet::should_add_blocker(Thread::Blocker& b, void*)
|
||||||
{
|
{
|
||||||
// NOTE: m_lock is held already!
|
// NOTE: m_lock is held already!
|
||||||
auto& blocker = static_cast<Blocker&>(b);
|
auto& blocker = static_cast<Blocker&>(b);
|
||||||
return !blocker.is_completed();
|
return !blocker.is_completed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plan9FS::Plan9FSBlockCondition::unblock_completed(u16 tag)
|
void Plan9FS::Plan9FSBlockerSet::unblock_completed(u16 tag)
|
||||||
{
|
{
|
||||||
unblock([&](Thread::Blocker& b, void*, bool&) {
|
unblock([&](Thread::Blocker& b, void*, bool&) {
|
||||||
VERIFY(b.blocker_type() == Thread::Blocker::Type::Plan9FS);
|
VERIFY(b.blocker_type() == Thread::Blocker::Type::Plan9FS);
|
||||||
|
@ -458,7 +458,7 @@ void Plan9FS::Plan9FSBlockCondition::unblock_completed(u16 tag)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plan9FS::Plan9FSBlockCondition::unblock_all()
|
void Plan9FS::Plan9FSBlockerSet::unblock_all()
|
||||||
{
|
{
|
||||||
unblock([&](Thread::Blocker& b, void*, bool&) {
|
unblock([&](Thread::Blocker& b, void*, bool&) {
|
||||||
VERIFY(b.blocker_type() == Thread::Blocker::Type::Plan9FS);
|
VERIFY(b.blocker_type() == Thread::Blocker::Type::Plan9FS);
|
||||||
|
@ -467,7 +467,7 @@ void Plan9FS::Plan9FSBlockCondition::unblock_all()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plan9FS::Plan9FSBlockCondition::try_unblock(Plan9FS::Blocker& blocker)
|
void Plan9FS::Plan9FSBlockerSet::try_unblock(Plan9FS::Blocker& blocker)
|
||||||
{
|
{
|
||||||
if (m_fs.is_complete(*blocker.completion())) {
|
if (m_fs.is_complete(*blocker.completion())) {
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
|
|
|
@ -50,9 +50,9 @@ private:
|
||||||
|
|
||||||
class Blocker;
|
class Blocker;
|
||||||
|
|
||||||
class Plan9FSBlockCondition final : public Thread::BlockCondition {
|
class Plan9FSBlockerSet final : public Thread::BlockerSet {
|
||||||
public:
|
public:
|
||||||
Plan9FSBlockCondition(Plan9FS& fs)
|
Plan9FSBlockerSet(Plan9FS& fs)
|
||||||
: m_fs(fs)
|
: m_fs(fs)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ private:
|
||||||
, m_message(message)
|
, m_message(message)
|
||||||
, m_completion(move(completion))
|
, m_completion(move(completion))
|
||||||
{
|
{
|
||||||
set_block_condition(fs.m_completion_blocker);
|
add_to_blocker_set(fs.m_completion_blocker);
|
||||||
}
|
}
|
||||||
virtual StringView state_string() const override { return "Waiting"sv; }
|
virtual StringView state_string() const override { return "Waiting"sv; }
|
||||||
virtual Type blocker_type() const override { return Type::Plan9FS; }
|
virtual Type blocker_type() const override { return Type::Plan9FS; }
|
||||||
|
@ -136,7 +136,7 @@ private:
|
||||||
size_t m_max_message_size { 4 * KiB };
|
size_t m_max_message_size { 4 * KiB };
|
||||||
|
|
||||||
Mutex m_send_lock { "Plan9FS send" };
|
Mutex m_send_lock { "Plan9FS send" };
|
||||||
Plan9FSBlockCondition m_completion_blocker;
|
Plan9FSBlockerSet m_completion_blocker;
|
||||||
HashMap<u16, NonnullRefPtr<ReceiveCompletion>> m_completions;
|
HashMap<u16, NonnullRefPtr<ReceiveCompletion>> m_completions;
|
||||||
|
|
||||||
Spinlock<u8> m_thread_lock;
|
Spinlock<u8> m_thread_lock;
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Kernel {
|
||||||
|
|
||||||
class FutexQueue final
|
class FutexQueue final
|
||||||
: public RefCounted<FutexQueue>
|
: public RefCounted<FutexQueue>
|
||||||
, public Thread::BlockCondition {
|
, public Thread::BlockerSet {
|
||||||
public:
|
public:
|
||||||
FutexQueue();
|
FutexQueue();
|
||||||
virtual ~FutexQueue();
|
virtual ~FutexQueue();
|
||||||
|
|
|
@ -55,11 +55,11 @@ private:
|
||||||
bool m_should_block { true };
|
bool m_should_block { true };
|
||||||
};
|
};
|
||||||
|
|
||||||
class ARPTableBlockCondition final : public Thread::BlockCondition {
|
class ARPTableBlockerSet final : public Thread::BlockerSet {
|
||||||
public:
|
public:
|
||||||
void unblock(const IPv4Address& ip_addr, const MACAddress& addr)
|
void unblock(const IPv4Address& ip_addr, const MACAddress& addr)
|
||||||
{
|
{
|
||||||
BlockCondition::unblock([&](auto& b, void*, bool&) {
|
BlockerSet::unblock([&](auto& b, void*, bool&) {
|
||||||
VERIFY(b.blocker_type() == Thread::Blocker::Type::Routing);
|
VERIFY(b.blocker_type() == Thread::Blocker::Type::Routing);
|
||||||
auto& blocker = static_cast<ARPTableBlocker&>(b);
|
auto& blocker = static_cast<ARPTableBlocker&>(b);
|
||||||
return blocker.unblock(false, ip_addr, addr);
|
return blocker.unblock(false, ip_addr, addr);
|
||||||
|
@ -80,13 +80,13 @@ protected:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static Singleton<ARPTableBlockCondition> s_arp_table_block_condition;
|
static Singleton<ARPTableBlockerSet> s_arp_table_block_condition;
|
||||||
|
|
||||||
ARPTableBlocker::ARPTableBlocker(IPv4Address ip_addr, Optional<MACAddress>& addr)
|
ARPTableBlocker::ARPTableBlocker(IPv4Address ip_addr, Optional<MACAddress>& addr)
|
||||||
: m_ip_addr(ip_addr)
|
: m_ip_addr(ip_addr)
|
||||||
, m_addr(addr)
|
, m_addr(addr)
|
||||||
{
|
{
|
||||||
if (!set_block_condition(*s_arp_table_block_condition))
|
if (!add_to_blocker_set(*s_arp_table_block_condition))
|
||||||
m_should_block = false;
|
m_should_block = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,7 @@ RefPtr<Process> Process::create_user_process(RefPtr<Thread>& first_thread, const
|
||||||
register_new(*process);
|
register_new(*process);
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
// NOTE: All user processes have a leaked ref on them. It's balanced by Thread::WaitBlockCondition::finalize().
|
// NOTE: All user processes have a leaked ref on them. It's balanced by Thread::WaitBlockerSet::finalize().
|
||||||
(void)process.leak_ref();
|
(void)process.leak_ref();
|
||||||
|
|
||||||
return process;
|
return process;
|
||||||
|
@ -656,7 +656,7 @@ void Process::finalize()
|
||||||
m_space->remove_all_regions({});
|
m_space->remove_all_regions({});
|
||||||
|
|
||||||
VERIFY(ref_count() > 0);
|
VERIFY(ref_count() > 0);
|
||||||
// WaitBlockCondition::finalize will be in charge of dropping the last
|
// WaitBlockerSet::finalize will be in charge of dropping the last
|
||||||
// reference if there are still waiters around, or whenever the last
|
// reference if there are still waiters around, or whenever the last
|
||||||
// waitable states are consumed. Unless there is no parent around
|
// waitable states are consumed. Unless there is no parent around
|
||||||
// anymore, in which case we'll just drop it right away.
|
// anymore, in which case we'll just drop it right away.
|
||||||
|
|
|
@ -485,7 +485,7 @@ public:
|
||||||
|
|
||||||
void disowned_by_waiter(Process& process);
|
void disowned_by_waiter(Process& process);
|
||||||
void unblock_waiters(Thread::WaitBlocker::UnblockFlags, u8 signal = 0);
|
void unblock_waiters(Thread::WaitBlocker::UnblockFlags, u8 signal = 0);
|
||||||
Thread::WaitBlockCondition& wait_block_condition() { return m_wait_block_condition; }
|
Thread::WaitBlockerSet& wait_blocker_set() { return m_wait_block_condition; }
|
||||||
|
|
||||||
template<typename Callback>
|
template<typename Callback>
|
||||||
void for_each_coredump_property(Callback callback) const
|
void for_each_coredump_property(Callback callback) const
|
||||||
|
@ -787,7 +787,7 @@ private:
|
||||||
// and wait for a tracer to attach.
|
// and wait for a tracer to attach.
|
||||||
bool m_wait_for_tracer_at_next_execve { false };
|
bool m_wait_for_tracer_at_next_execve { false };
|
||||||
|
|
||||||
Thread::WaitBlockCondition m_wait_block_condition;
|
Thread::WaitBlockerSet m_wait_block_condition;
|
||||||
|
|
||||||
struct CoredumpProperty {
|
struct CoredumpProperty {
|
||||||
OwnPtr<KString> key;
|
OwnPtr<KString> key;
|
||||||
|
|
|
@ -126,7 +126,7 @@ KResultOr<FlatPtr> Process::sys$fork(RegisterState& regs)
|
||||||
|
|
||||||
auto child_pid = child->pid().value();
|
auto child_pid = child->pid().value();
|
||||||
|
|
||||||
// NOTE: All user processes have a leaked ref on them. It's balanced by Thread::WaitBlockCondition::finalize().
|
// NOTE: All user processes have a leaked ref on them. It's balanced by Thread::WaitBlockerSet::finalize().
|
||||||
(void)child.leak_ref();
|
(void)child.leak_ref();
|
||||||
|
|
||||||
return child_pid;
|
return child_pid;
|
||||||
|
|
|
@ -112,9 +112,9 @@ String SlavePTY::device_name() const
|
||||||
return String::formatted("{}", minor());
|
return String::formatted("{}", minor());
|
||||||
}
|
}
|
||||||
|
|
||||||
FileBlockCondition& SlavePTY::block_condition()
|
FileBlockerSet& SlavePTY::blocker_set()
|
||||||
{
|
{
|
||||||
return m_master->block_condition();
|
return m_master->blocker_set();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
|
|
||||||
time_t time_of_last_write() const { return m_time_of_last_write; }
|
time_t time_of_last_write() const { return m_time_of_last_write; }
|
||||||
|
|
||||||
virtual FileBlockCondition& block_condition() override;
|
virtual FileBlockerSet& blocker_set() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// ^TTY
|
// ^TTY
|
||||||
|
|
|
@ -276,7 +276,7 @@ public:
|
||||||
bool m_should_block { false };
|
bool m_should_block { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlockCondition;
|
class BlockerSet;
|
||||||
|
|
||||||
class Blocker {
|
class Blocker {
|
||||||
public:
|
public:
|
||||||
|
@ -374,16 +374,13 @@ public:
|
||||||
thread->unblock_from_blocker(*this);
|
thread->unblock_from_blocker(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set_block_condition(BlockCondition&, void* = nullptr);
|
bool add_to_blocker_set(BlockerSet&, void* = nullptr);
|
||||||
void set_block_condition_raw_locked(BlockCondition* block_condition)
|
void set_blocker_set_raw_locked(BlockerSet* blocker_set) { m_blocker_set = blocker_set; }
|
||||||
{
|
|
||||||
m_block_condition = block_condition;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutable RecursiveSpinlock m_lock;
|
mutable RecursiveSpinlock m_lock;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BlockCondition* m_block_condition { nullptr };
|
BlockerSet* m_blocker_set { nullptr };
|
||||||
void* m_block_data { nullptr };
|
void* m_block_data { nullptr };
|
||||||
Thread* m_blocked_thread { nullptr };
|
Thread* m_blocked_thread { nullptr };
|
||||||
u8 m_was_interrupted_by_signal { 0 };
|
u8 m_was_interrupted_by_signal { 0 };
|
||||||
|
@ -392,14 +389,14 @@ public:
|
||||||
bool m_did_timeout { false };
|
bool m_did_timeout { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlockCondition {
|
class BlockerSet {
|
||||||
AK_MAKE_NONCOPYABLE(BlockCondition);
|
AK_MAKE_NONCOPYABLE(BlockerSet);
|
||||||
AK_MAKE_NONMOVABLE(BlockCondition);
|
AK_MAKE_NONMOVABLE(BlockerSet);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BlockCondition() = default;
|
BlockerSet() = default;
|
||||||
|
|
||||||
virtual ~BlockCondition()
|
virtual ~BlockerSet()
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
VERIFY(m_blockers.is_empty());
|
VERIFY(m_blockers.is_empty());
|
||||||
|
@ -738,11 +735,11 @@ public:
|
||||||
bool m_should_block;
|
bool m_should_block;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WaitBlockCondition final : public BlockCondition {
|
class WaitBlockerSet final : public BlockerSet {
|
||||||
friend class WaitBlocker;
|
friend class WaitBlocker;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WaitBlockCondition(Process& process)
|
explicit WaitBlockerSet(Process& process)
|
||||||
: m_process(process)
|
: m_process(process)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -1225,7 +1222,7 @@ private:
|
||||||
|
|
||||||
friend class WaitQueue;
|
friend class WaitQueue;
|
||||||
|
|
||||||
class JoinBlockCondition final : public BlockCondition {
|
class JoinBlockerSet final : public BlockerSet {
|
||||||
public:
|
public:
|
||||||
void thread_did_exit(void* exit_value)
|
void thread_did_exit(void* exit_value)
|
||||||
{
|
{
|
||||||
|
@ -1327,7 +1324,7 @@ private:
|
||||||
Vector<HoldingLockInfo> m_holding_locks_list;
|
Vector<HoldingLockInfo> m_holding_locks_list;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JoinBlockCondition m_join_condition;
|
JoinBlockerSet m_join_condition;
|
||||||
Atomic<bool, AK::MemoryOrder::memory_order_relaxed> m_is_active { false };
|
Atomic<bool, AK::MemoryOrder::memory_order_relaxed> m_is_active { false };
|
||||||
bool m_is_joinable { true };
|
bool m_is_joinable { true };
|
||||||
bool m_handling_page_fault { false };
|
bool m_handling_page_fault { false };
|
||||||
|
|
|
@ -28,11 +28,11 @@ Thread::BlockTimeout::BlockTimeout(bool is_absolute, const Time* time, const Tim
|
||||||
m_time += m_start_time;
|
m_time += m_start_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Thread::Blocker::set_block_condition(Thread::BlockCondition& block_condition, void* data)
|
bool Thread::Blocker::add_to_blocker_set(Thread::BlockerSet& blocker_set, void* data)
|
||||||
{
|
{
|
||||||
VERIFY(!m_block_condition);
|
VERIFY(!m_blocker_set);
|
||||||
if (block_condition.add_blocker(*this, data)) {
|
if (blocker_set.add_blocker(*this, data)) {
|
||||||
m_block_condition = &block_condition;
|
m_blocker_set = &blocker_set;
|
||||||
m_block_data = data;
|
m_block_data = data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,8 @@ bool Thread::Blocker::set_block_condition(Thread::BlockCondition& block_conditio
|
||||||
Thread::Blocker::~Blocker()
|
Thread::Blocker::~Blocker()
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
if (m_block_condition)
|
if (m_blocker_set)
|
||||||
m_block_condition->remove_blocker(*this, m_block_data);
|
m_blocker_set->remove_blocker(*this, m_block_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::Blocker::begin_blocking(Badge<Thread>)
|
void Thread::Blocker::begin_blocking(Badge<Thread>)
|
||||||
|
@ -78,7 +78,7 @@ Thread::JoinBlocker::JoinBlocker(Thread& joinee, KResult& try_join_result, void*
|
||||||
// but the joinee is joining immediately
|
// but the joinee is joining immediately
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
try_join_result = joinee.try_join([&]() {
|
try_join_result = joinee.try_join([&]() {
|
||||||
if (!set_block_condition(joinee.m_join_condition))
|
if (!add_to_blocker_set(joinee.m_join_condition))
|
||||||
m_should_block = false;
|
m_should_block = false;
|
||||||
});
|
});
|
||||||
m_join_error = try_join_result.is_error();
|
m_join_error = try_join_result.is_error();
|
||||||
|
@ -90,14 +90,14 @@ Thread::JoinBlocker::JoinBlocker(Thread& joinee, KResult& try_join_result, void*
|
||||||
void Thread::JoinBlocker::not_blocking(bool timeout_in_past)
|
void Thread::JoinBlocker::not_blocking(bool timeout_in_past)
|
||||||
{
|
{
|
||||||
if (!m_should_block) {
|
if (!m_should_block) {
|
||||||
// set_block_condition returned false, so unblock was already called
|
// add_to_blocker_set returned false, so unblock was already called
|
||||||
VERIFY(!timeout_in_past);
|
VERIFY(!timeout_in_past);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If we should have blocked but got here it must have been that the
|
// If we should have blocked but got here it must have been that the
|
||||||
// timeout was already in the past. So we need to ask the BlockCondition
|
// timeout was already in the past. So we need to ask the BlockerSet
|
||||||
// to supply us the information. We cannot hold the lock as unblock
|
// to supply us the information. We cannot hold the lock as unblock
|
||||||
// could be called by the BlockCondition at any time!
|
// could be called by the BlockerSet at any time!
|
||||||
VERIFY(timeout_in_past);
|
VERIFY(timeout_in_past);
|
||||||
m_joinee->m_join_condition.try_unblock(*this);
|
m_joinee->m_join_condition.try_unblock(*this);
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ bool Thread::JoinBlocker::unblock(void* value, bool from_add_blocker)
|
||||||
Thread::QueueBlocker::QueueBlocker(WaitQueue& wait_queue, StringView block_reason)
|
Thread::QueueBlocker::QueueBlocker(WaitQueue& wait_queue, StringView block_reason)
|
||||||
: m_block_reason(block_reason)
|
: m_block_reason(block_reason)
|
||||||
{
|
{
|
||||||
if (!set_block_condition(wait_queue, Thread::current()))
|
if (!add_to_blocker_set(wait_queue, Thread::current()))
|
||||||
m_should_block = false;
|
m_should_block = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ bool Thread::QueueBlocker::unblock()
|
||||||
Thread::FutexBlocker::FutexBlocker(FutexQueue& futex_queue, u32 bitset)
|
Thread::FutexBlocker::FutexBlocker(FutexQueue& futex_queue, u32 bitset)
|
||||||
: m_bitset(bitset)
|
: m_bitset(bitset)
|
||||||
{
|
{
|
||||||
if (!set_block_condition(futex_queue, Thread::current()))
|
if (!add_to_blocker_set(futex_queue, Thread::current()))
|
||||||
m_should_block = false;
|
m_should_block = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ Thread::FutexBlocker::~FutexBlocker()
|
||||||
void Thread::FutexBlocker::finish_requeue(FutexQueue& futex_queue)
|
void Thread::FutexBlocker::finish_requeue(FutexQueue& futex_queue)
|
||||||
{
|
{
|
||||||
VERIFY(m_lock.own_lock());
|
VERIFY(m_lock.own_lock());
|
||||||
set_block_condition_raw_locked(&futex_queue);
|
set_blocker_set_raw_locked(&futex_queue);
|
||||||
// We can now release the lock
|
// We can now release the lock
|
||||||
m_lock.unlock(m_relock_flags);
|
m_lock.unlock(m_relock_flags);
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ Thread::FileDescriptionBlocker::FileDescriptionBlocker(FileDescription& descript
|
||||||
, m_unblocked_flags(unblocked_flags)
|
, m_unblocked_flags(unblocked_flags)
|
||||||
{
|
{
|
||||||
m_unblocked_flags = BlockFlags::None;
|
m_unblocked_flags = BlockFlags::None;
|
||||||
if (!set_block_condition(description.block_condition()))
|
if (!add_to_blocker_set(description.blocker_set()))
|
||||||
m_should_block = false;
|
m_should_block = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,19 +220,19 @@ bool Thread::FileDescriptionBlocker::unblock(bool from_add_blocker, void*)
|
||||||
void Thread::FileDescriptionBlocker::not_blocking(bool timeout_in_past)
|
void Thread::FileDescriptionBlocker::not_blocking(bool timeout_in_past)
|
||||||
{
|
{
|
||||||
if (!m_should_block) {
|
if (!m_should_block) {
|
||||||
// set_block_condition returned false, so unblock was already called
|
// add_to_blocker_set returned false, so unblock was already called
|
||||||
VERIFY(!timeout_in_past);
|
VERIFY(!timeout_in_past);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If we should have blocked but got here it must have been that the
|
// If we should have blocked but got here it must have been that the
|
||||||
// timeout was already in the past. So we need to ask the BlockCondition
|
// timeout was already in the past. So we need to ask the BlockerSet
|
||||||
// to supply us the information. We cannot hold the lock as unblock
|
// to supply us the information. We cannot hold the lock as unblock
|
||||||
// could be called by the BlockCondition at any time!
|
// could be called by the BlockerSet at any time!
|
||||||
VERIFY(timeout_in_past);
|
VERIFY(timeout_in_past);
|
||||||
|
|
||||||
// Just call unblock here because we will query the file description
|
// Just call unblock here because we will query the file description
|
||||||
// for the data and don't need any input from the FileBlockCondition.
|
// for the data and don't need any input from the FileBlockerSet.
|
||||||
// However, it's possible that if timeout_in_past is true then FileBlockCondition
|
// However, it's possible that if timeout_in_past is true then FileBlockerSet
|
||||||
// may call us at any given time, so our call to unblock here may fail.
|
// may call us at any given time, so our call to unblock here may fail.
|
||||||
// Either way, unblock will be called at least once, which provides
|
// Either way, unblock will be called at least once, which provides
|
||||||
// all the data we need.
|
// all the data we need.
|
||||||
|
@ -349,7 +349,7 @@ Thread::SelectBlocker::SelectBlocker(FDVector& fds)
|
||||||
|
|
||||||
if (!m_should_block)
|
if (!m_should_block)
|
||||||
continue;
|
continue;
|
||||||
if (!fd_entry.description->block_condition().add_blocker(*this, &fd_entry))
|
if (!fd_entry.description->blocker_set().add_blocker(*this, &fd_entry))
|
||||||
m_should_block = false;
|
m_should_block = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,7 +357,7 @@ Thread::SelectBlocker::SelectBlocker(FDVector& fds)
|
||||||
Thread::SelectBlocker::~SelectBlocker()
|
Thread::SelectBlocker::~SelectBlocker()
|
||||||
{
|
{
|
||||||
for (auto& fd_entry : m_fds)
|
for (auto& fd_entry : m_fds)
|
||||||
fd_entry.description->block_condition().remove_blocker(*this, &fd_entry);
|
fd_entry.description->blocker_set().remove_blocker(*this, &fd_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::SelectBlocker::not_blocking(bool timeout_in_past)
|
void Thread::SelectBlocker::not_blocking(bool timeout_in_past)
|
||||||
|
@ -434,18 +434,18 @@ void Thread::SelectBlocker::was_unblocked(bool did_timeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::WaitBlockCondition::ProcessBlockInfo::ProcessBlockInfo(NonnullRefPtr<Process>&& process, WaitBlocker::UnblockFlags flags, u8 signal)
|
Thread::WaitBlockerSet::ProcessBlockInfo::ProcessBlockInfo(NonnullRefPtr<Process>&& process, WaitBlocker::UnblockFlags flags, u8 signal)
|
||||||
: process(move(process))
|
: process(move(process))
|
||||||
, flags(flags)
|
, flags(flags)
|
||||||
, signal(signal)
|
, signal(signal)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::WaitBlockCondition::ProcessBlockInfo::~ProcessBlockInfo()
|
Thread::WaitBlockerSet::ProcessBlockInfo::~ProcessBlockInfo()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::WaitBlockCondition::try_unblock(Thread::WaitBlocker& blocker)
|
void Thread::WaitBlockerSet::try_unblock(Thread::WaitBlocker& blocker)
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
// We if we have any processes pending
|
// We if we have any processes pending
|
||||||
|
@ -459,9 +459,9 @@ void Thread::WaitBlockCondition::try_unblock(Thread::WaitBlocker& blocker)
|
||||||
if (blocker.is_wait()) {
|
if (blocker.is_wait()) {
|
||||||
if (info.flags == Thread::WaitBlocker::UnblockFlags::Terminated) {
|
if (info.flags == Thread::WaitBlocker::UnblockFlags::Terminated) {
|
||||||
m_processes.remove(i);
|
m_processes.remove(i);
|
||||||
dbgln_if(WAITBLOCK_DEBUG, "WaitBlockCondition[{}] terminated, remove {}", m_process, *info.process);
|
dbgln_if(WAITBLOCK_DEBUG, "WaitBlockerSet[{}] terminated, remove {}", m_process, *info.process);
|
||||||
} else {
|
} else {
|
||||||
dbgln_if(WAITBLOCK_DEBUG, "WaitBlockCondition[{}] terminated, mark as waited {}", m_process, *info.process);
|
dbgln_if(WAITBLOCK_DEBUG, "WaitBlockerSet[{}] terminated, mark as waited {}", m_process, *info.process);
|
||||||
info.was_waited = true;
|
info.was_waited = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,7 +470,7 @@ void Thread::WaitBlockCondition::try_unblock(Thread::WaitBlocker& blocker)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::WaitBlockCondition::disowned_by_waiter(Process& process)
|
void Thread::WaitBlockerSet::disowned_by_waiter(Process& process)
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
if (m_finalized)
|
if (m_finalized)
|
||||||
|
@ -485,7 +485,7 @@ void Thread::WaitBlockCondition::disowned_by_waiter(Process& process)
|
||||||
VERIFY(did_unblock); // disowning must unblock everyone
|
VERIFY(did_unblock); // disowning must unblock everyone
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
dbgln_if(WAITBLOCK_DEBUG, "WaitBlockCondition[{}] disowned {}", m_process, *info.process);
|
dbgln_if(WAITBLOCK_DEBUG, "WaitBlockerSet[{}] disowned {}", m_process, *info.process);
|
||||||
m_processes.remove(i);
|
m_processes.remove(i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -494,7 +494,7 @@ void Thread::WaitBlockCondition::disowned_by_waiter(Process& process)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Thread::WaitBlockCondition::unblock(Process& process, WaitBlocker::UnblockFlags flags, u8 signal)
|
bool Thread::WaitBlockerSet::unblock(Process& process, WaitBlocker::UnblockFlags flags, u8 signal)
|
||||||
{
|
{
|
||||||
VERIFY(flags != WaitBlocker::UnblockFlags::Disowned);
|
VERIFY(flags != WaitBlocker::UnblockFlags::Disowned);
|
||||||
|
|
||||||
|
@ -538,20 +538,20 @@ bool Thread::WaitBlockCondition::unblock(Process& process, WaitBlocker::UnblockF
|
||||||
info.flags = flags;
|
info.flags = flags;
|
||||||
info.signal = signal;
|
info.signal = signal;
|
||||||
info.was_waited = did_wait;
|
info.was_waited = did_wait;
|
||||||
dbgln_if(WAITBLOCK_DEBUG, "WaitBlockCondition[{}] update {} flags={}, waited={}", m_process, process, (int)flags, info.was_waited);
|
dbgln_if(WAITBLOCK_DEBUG, "WaitBlockerSet[{}] update {} flags={}, waited={}", m_process, process, (int)flags, info.was_waited);
|
||||||
updated_existing = true;
|
updated_existing = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!updated_existing) {
|
if (!updated_existing) {
|
||||||
dbgln_if(WAITBLOCK_DEBUG, "WaitBlockCondition[{}] add {} flags: {}", m_process, process, (int)flags);
|
dbgln_if(WAITBLOCK_DEBUG, "WaitBlockerSet[{}] add {} flags: {}", m_process, process, (int)flags);
|
||||||
m_processes.append(ProcessBlockInfo(process, flags, signal));
|
m_processes.append(ProcessBlockInfo(process, flags, signal));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return did_unblock_any;
|
return did_unblock_any;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Thread::WaitBlockCondition::should_add_blocker(Blocker& b, void*)
|
bool Thread::WaitBlockerSet::should_add_blocker(Blocker& b, void*)
|
||||||
{
|
{
|
||||||
// NOTE: m_lock is held already!
|
// NOTE: m_lock is held already!
|
||||||
if (m_finalized)
|
if (m_finalized)
|
||||||
|
@ -571,7 +571,7 @@ bool Thread::WaitBlockCondition::should_add_blocker(Blocker& b, void*)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::WaitBlockCondition::finalize()
|
void Thread::WaitBlockerSet::finalize()
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(m_lock);
|
SpinlockLocker lock(m_lock);
|
||||||
VERIFY(!m_finalized);
|
VERIFY(!m_finalized);
|
||||||
|
@ -619,10 +619,10 @@ Thread::WaitBlocker::WaitBlocker(int wait_options, idtype_t id_type, pid_t id, K
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: unblock may be called within set_block_condition, in which
|
// NOTE: unblock may be called within add_to_blocker_set, in which
|
||||||
// case it means that we already have a match without having to block.
|
// case it means that we already have a match without having to block.
|
||||||
// In that case set_block_condition will return false.
|
// In that case add_to_blocker_set will return false.
|
||||||
if (m_error || !set_block_condition(Process::current().wait_block_condition()))
|
if (m_error || !add_to_blocker_set(Process::current().wait_blocker_set()))
|
||||||
m_should_block = false;
|
m_should_block = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,7 +630,7 @@ void Thread::WaitBlocker::not_blocking(bool timeout_in_past)
|
||||||
{
|
{
|
||||||
VERIFY(timeout_in_past || !m_should_block);
|
VERIFY(timeout_in_past || !m_should_block);
|
||||||
if (!m_error)
|
if (!m_error)
|
||||||
Process::current().wait_block_condition().try_unblock(*this);
|
Process::current().wait_blocker_set().try_unblock(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::WaitBlocker::was_unblocked(bool)
|
void Thread::WaitBlocker::was_unblocked(bool)
|
||||||
|
@ -643,7 +643,7 @@ void Thread::WaitBlocker::was_unblocked(bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (try_unblock)
|
if (try_unblock)
|
||||||
Process::current().wait_block_condition().try_unblock(*this);
|
Process::current().wait_blocker_set().try_unblock(*this);
|
||||||
|
|
||||||
// If we were interrupted by SIGCHLD (which gets special handling
|
// If we were interrupted by SIGCHLD (which gets special handling
|
||||||
// here) we're not going to return with EINTR. But we're going to
|
// here) we're not going to return with EINTR. But we're going to
|
||||||
|
@ -768,7 +768,7 @@ bool Thread::WaitBlocker::unblock(Process& process, UnblockFlags flags, u8 signa
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!from_add_blocker) {
|
if (!from_add_blocker) {
|
||||||
// Only call unblock if we weren't called from within set_block_condition!
|
// Only call unblock if we weren't called from within add_to_blocker_set!
|
||||||
VERIFY(flags != UnblockFlags::Disowned);
|
VERIFY(flags != UnblockFlags::Disowned);
|
||||||
unblock_from_blocker();
|
unblock_from_blocker();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
class WaitQueue final : public Thread::BlockCondition {
|
class WaitQueue final : public Thread::BlockerSet {
|
||||||
public:
|
public:
|
||||||
u32 wake_one();
|
u32 wake_one();
|
||||||
u32 wake_n(u32 wake_count);
|
u32 wake_n(u32 wake_count);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue