mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 01:35:08 +02:00
LibCore: Add a thread-safe weak link for EventLoop
Since the event loop has a very specifically scoped lifetime, we can't ensure that it outlives threads that hold a reference to it without blocking the thread that owns it. In order to make threads use the event loop safely, we now have an atomically ref-counted WeakEventLoopReference class that can be passed off to threads to safely post events/callbacks to it. Another possibility was to use an RWLock per event loop that each thread holds a read lock on, while ~EventLoop() uses a write lock to block and prevent it being destroyed until all its threads exit. However, media data providers don't receive a signal to exit due to the GC heap being intentionally leaked, so the process never actually exits. It would be possible to specifically drop the reference to PlaybackManager in HTMLMediaElement in order to make those data providers die on their own, but that doesn't help prevent this problem in other cases where it may arise.
This commit is contained in:
committed by
Gregory Bertilson
parent
8289b24a7e
commit
2a5a9d2103
Notes:
github-actions[bot]
2025-12-09 22:14:13 +00:00
Author: https://github.com/Zaggy1024 Commit: https://github.com/LadybirdBrowser/ladybird/commit/2a5a9d21032 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/7039 Reviewed-by: https://github.com/R-Goc
@@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/AtomicRefCounted.h>
|
||||
#include <AK/Forward.h>
|
||||
#include <AK/Function.h>
|
||||
#include <AK/Noncopyable.h>
|
||||
@@ -16,11 +17,13 @@
|
||||
#include <AK/Time.h>
|
||||
#include <LibCore/Event.h>
|
||||
#include <LibCore/Forward.h>
|
||||
#include <LibThreading/RWLock.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class EventLoopImplementation;
|
||||
class ThreadEventQueue;
|
||||
class WeakEventLoopReference;
|
||||
|
||||
// The event loop enables asynchronous (not parallel or multi-threaded) computing by efficiently handling events from various sources.
|
||||
// Event loops are most important for GUI programs, where the various GUI updates and action callbacks run on the EventLoop,
|
||||
@@ -89,13 +92,50 @@ public:
|
||||
|
||||
static bool is_running();
|
||||
static EventLoop& current();
|
||||
static NonnullRefPtr<WeakEventLoopReference> current_weak();
|
||||
|
||||
EventLoopImplementation& impl() { return *m_impl; }
|
||||
|
||||
private:
|
||||
NonnullOwnPtr<EventLoopImplementation> m_impl;
|
||||
RefPtr<WeakEventLoopReference> m_weak;
|
||||
} SWIFT_UNSAFE_REFERENCE;
|
||||
|
||||
class StrongEventLoopReference;
|
||||
|
||||
class WeakEventLoopReference : public AtomicRefCounted<WeakEventLoopReference> {
|
||||
public:
|
||||
StrongEventLoopReference take();
|
||||
|
||||
private:
|
||||
friend class EventLoop;
|
||||
friend class StrongEventLoopReference;
|
||||
|
||||
WeakEventLoopReference(EventLoop&);
|
||||
|
||||
void revoke();
|
||||
|
||||
EventLoop* m_event_loop;
|
||||
Threading::RWLock m_lock;
|
||||
};
|
||||
|
||||
class StrongEventLoopReference {
|
||||
public:
|
||||
~StrongEventLoopReference();
|
||||
|
||||
bool is_alive() const;
|
||||
operator bool() const;
|
||||
EventLoop* operator*() const;
|
||||
EventLoop* operator->() const;
|
||||
|
||||
private:
|
||||
friend class WeakEventLoopReference;
|
||||
|
||||
StrongEventLoopReference(WeakEventLoopReference&);
|
||||
|
||||
WeakEventLoopReference* m_event_loop_weak;
|
||||
};
|
||||
|
||||
void deferred_invoke(ESCAPING Function<void()>);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user