mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibThread: Improve semantics of Thread::join, and remove Thread::quit.
Thread::quit was created before the pthread_create_helper in pthread.cpp that automagically calls pthread_exit from all pthreads after the user's thread function exits. It is unused, and unecessary now. Cleanup some logging, and make join return a Result<T, ThreadError>. This also adds a new type, LibThread::ThreadError as an AK::DistinctNumeric. Hopefully, this will make it possible to have a Result<int, ThreadError> and have it compile? It also makes it clear that the int there is an error at the call site. By default, the T on join is void, meaning the caller doesn't care about the return value from the thread. As Result is a [[nodiscard]] type, also change the current caller of join to explicitly ignore it. Move the logging out of join as well, as it's the user's responsibility whether to log or not.
This commit is contained in:
parent
986544600a
commit
8d0b4657e7
Notes:
sideshowbarker
2024-07-19 00:15:03 +09:00
Author: https://github.com/ADKaster Commit: https://github.com/SerenityOS/serenity/commit/8d0b4657e7f Pull-request: https://github.com/SerenityOS/serenity/pull/4705 Reviewed-by: https://github.com/tomuta
3 changed files with 32 additions and 24 deletions
|
@ -34,13 +34,15 @@ LibThread::Thread::Thread(Function<int()> action, StringView thread_name)
|
|||
, m_action(move(action))
|
||||
, m_thread_name(thread_name.is_null() ? "" : thread_name)
|
||||
{
|
||||
register_property("thread_name", [&] { return JsonValue { m_thread_name }; });
|
||||
register_property("tid", [&] { return JsonValue { m_tid }; });
|
||||
}
|
||||
|
||||
LibThread::Thread::~Thread()
|
||||
{
|
||||
if (m_tid) {
|
||||
dbg() << "trying to destroy a running thread!";
|
||||
join();
|
||||
dbgln("Destroying thread \"{}\"({}) while it is still running!", m_thread_name, m_tid);
|
||||
[[maybe_unused]] auto res = join();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +53,7 @@ void LibThread::Thread::start()
|
|||
nullptr,
|
||||
[](void* arg) -> void* {
|
||||
Thread* self = static_cast<Thread*>(arg);
|
||||
size_t exit_code = self->m_action();
|
||||
int exit_code = self->m_action();
|
||||
self->m_tid = 0;
|
||||
return (void*)exit_code;
|
||||
},
|
||||
|
@ -62,22 +64,5 @@ void LibThread::Thread::start()
|
|||
rc = pthread_setname_np(m_tid, m_thread_name.characters());
|
||||
ASSERT(rc == 0);
|
||||
}
|
||||
dbg() << "Started a thread, tid = " << m_tid;
|
||||
}
|
||||
|
||||
void LibThread::Thread::join()
|
||||
{
|
||||
int rc = pthread_join(m_tid, nullptr);
|
||||
if (rc == 0)
|
||||
m_tid = 0;
|
||||
else
|
||||
warnln("pthread_join: {}", strerror(rc));
|
||||
}
|
||||
|
||||
void LibThread::Thread::quit(void* code)
|
||||
{
|
||||
ASSERT(m_tid == pthread_self());
|
||||
|
||||
m_tid = 0;
|
||||
pthread_exit(code);
|
||||
dbgln("Started thread \"{}\", tid = {}", m_thread_name, m_tid);
|
||||
}
|
||||
|
|
|
@ -26,13 +26,17 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/DistinctNumeric.h>
|
||||
#include <AK/Function.h>
|
||||
#include <AK/Result.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibCore/Object.h>
|
||||
#include <pthread.h>
|
||||
|
||||
namespace LibThread {
|
||||
|
||||
TYPEDEF_DISTINCT_ORDERED_ID(int, ThreadError);
|
||||
|
||||
class Thread final : public Core::Object {
|
||||
C_OBJECT(Thread);
|
||||
|
||||
|
@ -40,8 +44,11 @@ public:
|
|||
virtual ~Thread();
|
||||
|
||||
void start();
|
||||
void join();
|
||||
void quit(void* code = 0);
|
||||
|
||||
template<typename T = void>
|
||||
Result<T, ThreadError> join();
|
||||
|
||||
String thread_name() const { return m_thread_name; }
|
||||
pthread_t tid() const { return m_tid; }
|
||||
|
||||
private:
|
||||
|
@ -51,4 +58,20 @@ private:
|
|||
String m_thread_name;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Result<T, ThreadError> Thread::join()
|
||||
{
|
||||
void* thread_return = nullptr;
|
||||
int rc = pthread_join(m_tid, &thread_return);
|
||||
if (rc != 0) {
|
||||
return ThreadError { rc };
|
||||
}
|
||||
|
||||
m_tid = 0;
|
||||
if constexpr (IsVoid<T>::value)
|
||||
return {};
|
||||
else
|
||||
return { static_cast<T>(thread_return) };
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ static void test_once()
|
|||
threads.last().start();
|
||||
}
|
||||
for (auto& thread : threads)
|
||||
thread.join();
|
||||
[[maybe_unused]] auto res = thread.join();
|
||||
|
||||
ASSERT(v.size() == 1);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue