Repository: LadybirdBrowser/ladybird
File: Libraries/LibWebView/EventLoop/EventLoopImplementationQt.cpp (C++)

Code before:

namespace WebView {

struct ThreadData;
static thread_local OwnPtr<ThreadData> s_this_thread_data;
static HashMap<pthread_t, ThreadData*> s_thread_data;
static thread_local pthread_t s_thread_id;
static pthread_key_t s_thread_key;
static pthread_rwlock_t s_thread_data_lock_impl;
static pthread_rwlock_t* s_thread_data_lock = nullptr;

struct ThreadData {
    static ThreadData& the()
    {
        if (!s_thread_data_lock) {
            pthread_rwlock_init(&s_thread_data_lock_impl, nullptr);
            s_thread_data_lock = &s_thread_data_lock_impl;
            pthread_key_create(&s_thread_key, [](void*) {
                s_this_thread_data.clear();
            });
        }
        if (s_thread_id == 0)
            s_thread_id = pthread_self();
        if (!s_this_thread_data) {
            s_this_thread_data = make<ThreadData>();
            pthread_rwlock_wrlock(&*s_thread_data_lock);
            s_thread_data.set(s_thread_id, s_this_thread_data);
            pthread_rwlock_unlock(&*s_thread_data_lock);
        }
        return *s_this_thread_data;
    }

    static ThreadData* for_thread(pthread_t thread_id)
    {
        pthread_rwlock_rdlock(&*s_thread_data_lock);
        auto* result = s_thread_data.get(thread_id).value_or(nullptr);
        pthread_rwlock_unlock(&*s_thread_data_lock);
        return result;
    }

    ~ThreadData()
    {
        pthread_rwlock_wrlock(&*s_thread_data_lock);
        s_thread_data.remove(s_thread_id);
        pthread_rwlock_unlock(&*s_thread_data_lock);
    }

    Threading::Mutex mutex;
    HashMap<Core::Notifier*, NonnullOwnPtr<QSocketNotifier>> notifiers;
};


Review comment (suggestion):
(If we can't use RWLock) - de-referencing and then taking the address seems weird. Is this any different than just:
```c++
pthread_rwlock_wrlock(s_thread_data_lock);
```

Code after:
#include <QTimer>

namespace WebView {

struct ThreadData;
static thread_local OwnPtr<ThreadData> s_this_thread_data;
static HashMap<pthread_t, ThreadData*> s_thread_data;
static Threading::RWLock s_thread_data_lock;
static thread_local pthread_t s_thread_id;

struct ThreadData {
    static ThreadData& the()
    {
        if (s_thread_id == 0)
            s_thread_id = pthread_self();
        if (!s_this_thread_data) {
            s_this_thread_data = make<ThreadData>();
            Threading::RWLockLocker<Threading::LockMode::Write> locker(s_thread_data_lock);
            s_thread_data.set(s_thread_id, s_this_thread_data.ptr());
        }
        return *s_this_thread_data;
    }

    static ThreadData* for_thread(pthread_t thread_id)
    {
        Threading::RWLockLocker<Threading::LockMode::Read> locker(s_thread_data_lock);
        return s_thread_data.get(thread_id).value_or(nullptr);
    }

    ~ThreadData()
    {
        Threading::RWLockLocker<Threading::LockMode::Write> locker(s_thread_data_lock);
        s_thread_data.remove(s_thread_id);
    }

    Threading::Mutex mutex;
    HashMap<Core::Notifier*, NonnullOwnPtr<QSocketNotifier>> notifiers;
};

class QtEventLoopManagerEvent final : public QEvent {
public:
    static QEvent::Type process_event_queue_event_type()
    {
        static auto const type = static_cast<QEvent::Type>(QEvent::registerEventType());
        return type;
    }

    QtEventLoopManagerEvent(QEvent::Type type)
        : QEvent(type)
    {
    }