LibThreading: Add possibility to set threads detached before start

This commit is contained in:
Gabriele 2025-03-21 15:56:09 +01:00
commit e50a81abf7
2 changed files with 16 additions and 4 deletions

View file

@ -43,6 +43,11 @@ ErrorOr<int> Thread::get_priority() const
return scheduling_parameters.sched_priority; return scheduling_parameters.sched_priority;
} }
void Thread::set_detached_on_start()
{
m_attribute_detached_flag = true;
}
ByteString Thread::thread_name() const { return m_thread_name; } ByteString Thread::thread_name() const { return m_thread_name; }
pthread_t Thread::tid() const { return m_tid; } pthread_t Thread::tid() const { return m_tid; }
@ -68,18 +73,21 @@ void Thread::start()
VERIFY(!is_started()); VERIFY(!is_started());
// Set this first so that the other thread starts out seeing m_state == Running. // Set this first so that the other thread starts out seeing m_state == Running.
m_state = Threading::ThreadState::Running; m_state = m_attribute_detached_flag ? Threading::ThreadState::Detached : Threading::ThreadState::Running;
pthread_attr_init(&m_attribute);
if (m_attribute_detached_flag) {
pthread_attr_setdetachstate(&m_attribute, PTHREAD_CREATE_DETACHED);
}
int rc = pthread_create( int rc = pthread_create(
&m_tid, &m_tid,
// FIXME: Use pthread_attr_t to start a thread detached if that was requested by the user before the call to start(). &m_attribute,
nullptr,
[](void* arg) -> void* { [](void* arg) -> void* {
auto self = adopt_ref(*static_cast<Thread*>(arg)); auto self = adopt_ref(*static_cast<Thread*>(arg));
auto exit_code = self->m_action(); auto exit_code = self->m_action();
auto expected = Threading::ThreadState::Running; auto expected = Threading::ThreadState::Running;
// This code might race with a call to detach(). // This code might race with a call to detach().
if (!self->m_state.compare_exchange_strong(expected, Threading::ThreadState::Exited)) { if (!self->m_state.compare_exchange_strong(expected, Threading::ThreadState::Exited)) {
// If the original state was Detached, we need to set to DetachedExited instead. // If the original state was Detached, we need to set to DetachedExited instead.
@ -97,6 +105,7 @@ void Thread::start()
return reinterpret_cast<void*>(exit_code); return reinterpret_cast<void*>(exit_code);
}, },
&NonnullRefPtr(*this).leak_ref()); &NonnullRefPtr(*this).leak_ref());
pthread_attr_destroy(&m_attribute);
VERIFY(rc == 0); VERIFY(rc == 0);
} }

View file

@ -60,6 +60,7 @@ public:
ErrorOr<void> set_priority(int priority); ErrorOr<void> set_priority(int priority);
ErrorOr<int> get_priority() const; ErrorOr<int> get_priority() const;
void set_detached_on_start();
// Only callable in the Startable state. // Only callable in the Startable state.
void start(); void start();
// Only callable in the Running state. // Only callable in the Running state.
@ -80,6 +81,8 @@ private:
explicit Thread(ESCAPING Function<intptr_t()> action, StringView thread_name = {}); explicit Thread(ESCAPING Function<intptr_t()> action, StringView thread_name = {});
Function<intptr_t()> m_action; Function<intptr_t()> m_action;
pthread_t m_tid {}; pthread_t m_tid {};
pthread_attr_t m_attribute;
bool m_attribute_detached_flag = { false };
ByteString m_thread_name; ByteString m_thread_name;
Atomic<ThreadState> m_state { ThreadState::Startable }; Atomic<ThreadState> m_state { ThreadState::Startable };
}; };