mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 03:25:13 +00:00
LibCore: Check for null ThreadData in unregister_notifier
and unregister_timer in EventLoopManagerWindows Destructors for thread local objects are called before destructors of global not thread local objects. This is a partial stack of the problem, thread_data is already destroyed at this point: >WebContent.exe!Core::ThreadData::the WebContent.exe!Core::EventLoopManagerWindows::unregister_notifier WebContent.exe!Core::EventLoop::unregister_notifier WebContent.exe!Core::Notifier::set_enabled WebContent.exe!Core::LocalSocket::~LocalSocket WebContent.exe!Requests::RequestClient::~RequestClient WebContent.exe!Web::`dynamic atexit destructor for 's_resource_loader'
This commit is contained in:
parent
b53694b4c0
commit
33457f389d
Notes:
github-actions[bot]
2025-04-11 01:03:27 +00:00
Author: https://github.com/stasoid Commit: https://github.com/LadybirdBrowser/ladybird/commit/33457f389d7 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3188 Reviewed-by: https://github.com/ADKaster ✅
1 changed files with 16 additions and 12 deletions
|
@ -55,10 +55,12 @@ struct EventLoopTimer {
|
|||
};
|
||||
|
||||
struct ThreadData {
|
||||
static ThreadData& the()
|
||||
static ThreadData* the()
|
||||
{
|
||||
thread_local OwnPtr<ThreadData> thread_data = make<ThreadData>();
|
||||
return *thread_data;
|
||||
if (thread_data)
|
||||
return &*thread_data;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ThreadData()
|
||||
|
@ -76,7 +78,7 @@ struct ThreadData {
|
|||
};
|
||||
|
||||
EventLoopImplementationWindows::EventLoopImplementationWindows()
|
||||
: m_wake_event(ThreadData::the().wake_event.handle)
|
||||
: m_wake_event(ThreadData::the()->wake_event.handle)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -92,9 +94,9 @@ int EventLoopImplementationWindows::exec()
|
|||
|
||||
size_t EventLoopImplementationWindows::pump(PumpMode)
|
||||
{
|
||||
auto& thread_data = ThreadData::the();
|
||||
auto& notifiers = thread_data.notifiers;
|
||||
auto& timers = thread_data.timers;
|
||||
auto thread_data = ThreadData::the();
|
||||
auto& notifiers = thread_data->notifiers;
|
||||
auto& timers = thread_data->timers;
|
||||
|
||||
size_t event_count = 1 + notifiers.size() + timers.size();
|
||||
// If 64 events limit proves to be insufficient RegisterWaitForSingleObject or other methods
|
||||
|
@ -103,7 +105,7 @@ size_t EventLoopImplementationWindows::pump(PumpMode)
|
|||
VERIFY(event_count <= MAXIMUM_WAIT_OBJECTS);
|
||||
|
||||
Vector<HANDLE, MAXIMUM_WAIT_OBJECTS> event_handles;
|
||||
event_handles.append(thread_data.wake_event.handle);
|
||||
event_handles.append(thread_data->wake_event.handle);
|
||||
|
||||
for (auto& entry : notifiers)
|
||||
event_handles.append(entry.key.handle);
|
||||
|
@ -167,7 +169,7 @@ void EventLoopManagerWindows::register_notifier(Notifier& notifier)
|
|||
int rc = WSAEventSelect(notifier.fd(), event, notifier_type_to_network_event(notifier.type()));
|
||||
VERIFY(!rc);
|
||||
|
||||
auto& notifiers = ThreadData::the().notifiers;
|
||||
auto& notifiers = ThreadData::the()->notifiers;
|
||||
VERIFY(!notifiers.get(event).has_value());
|
||||
notifiers.set(Handle(event), ¬ifier);
|
||||
}
|
||||
|
@ -175,7 +177,8 @@ void EventLoopManagerWindows::register_notifier(Notifier& notifier)
|
|||
void EventLoopManagerWindows::unregister_notifier(Notifier& notifier)
|
||||
{
|
||||
// remove_first_matching would be clearer, but currently there is no such method in HashMap
|
||||
ThreadData::the().notifiers.remove_all_matching([&](auto&, auto value) { return value == ¬ifier; });
|
||||
if (ThreadData::the())
|
||||
ThreadData::the()->notifiers.remove_all_matching([&](auto&, auto value) { return value == ¬ifier; });
|
||||
}
|
||||
|
||||
intptr_t EventLoopManagerWindows::register_timer(EventReceiver& object, int milliseconds, bool should_reload, TimerShouldFireWhenNotVisible fire_when_not_visible)
|
||||
|
@ -190,15 +193,16 @@ intptr_t EventLoopManagerWindows::register_timer(EventReceiver& object, int mill
|
|||
BOOL rc = SetWaitableTimer(timer, &first_time, should_reload ? milliseconds : 0, NULL, NULL, FALSE);
|
||||
VERIFY(rc);
|
||||
|
||||
auto& timers = ThreadData::the().timers;
|
||||
auto& timers = ThreadData::the()->timers;
|
||||
VERIFY(!timers.get(timer).has_value());
|
||||
timers.set(Handle(timer), { object, fire_when_not_visible });
|
||||
return (intptr_t)timer;
|
||||
return reinterpret_cast<intptr_t>(timer);
|
||||
}
|
||||
|
||||
void EventLoopManagerWindows::unregister_timer(intptr_t timer_id)
|
||||
{
|
||||
ThreadData::the().timers.remove((HANDLE)timer_id);
|
||||
if (ThreadData::the())
|
||||
ThreadData::the()->timers.remove(reinterpret_cast<HANDLE>(timer_id));
|
||||
}
|
||||
|
||||
int EventLoopManagerWindows::register_signal([[maybe_unused]] int signal_number, [[maybe_unused]] Function<void(int)> handler)
|
||||
|
|
Loading…
Add table
Reference in a new issue