Ladybird/AppKit: Retrieve socket notifiers from the local thread data

For some reason, we occasionally receive a junk `info` pointer from the
CFSocketCallback we create for socket notifiers. Instead of capturing a
pointer to the local Core::Notifier for this `info` member, grab it from
the thread data instance based on the socket FD.

This was mostly seen when spamming new window requests to an existing
Ladybird process.
This commit is contained in:
Timothy Flynn 2024-04-28 12:15:40 -04:00 committed by Andrew Kaster
parent 478ceb71ec
commit 606df46e46
Notes: sideshowbarker 2024-07-18 05:01:22 +09:00

View File

@ -23,6 +23,17 @@ struct ThreadData {
return s_thread_data;
}
Core::Notifier& notifier_by_fd(int fd)
{
for (auto notifier : notifiers) {
if (notifier.key->fd() == fd)
return *notifier.key;
}
// If we didn't have a notifier for the provided FD, it should have been unregistered.
VERIFY_NOT_REACHED();
}
IDAllocator timer_id_allocator;
HashMap<int, CFRunLoopTimerRef> timers;
HashMap<Core::Notifier*, CFRunLoopSourceRef> notifiers;
@ -93,9 +104,9 @@ void CFEventLoopManager::unregister_timer(intptr_t timer_id)
CFRelease(*timer);
}
static void socket_notifier(CFSocketRef socket, CFSocketCallBackType notification_type, CFDataRef, void const*, void* info)
static void socket_notifier(CFSocketRef socket, CFSocketCallBackType notification_type, CFDataRef, void const*, void*)
{
auto& notifier = *reinterpret_cast<Core::Notifier*>(info);
auto& notifier = ThreadData::the().notifier_by_fd(CFSocketGetNative(socket));
// This socket callback is not quite re-entrant. If Core::Notifier::dispatch_event blocks, e.g.
// to wait upon a Core::Promise, this socket will not receive any more notifications until that
@ -127,7 +138,7 @@ void CFEventLoopManager::register_notifier(Core::Notifier& notifier)
break;
}
CFSocketContext context { .version = 0, .info = &notifier, .retain = nullptr, .release = nullptr, .copyDescription = nullptr };
CFSocketContext context { .version = 0, .info = nullptr, .retain = nullptr, .release = nullptr, .copyDescription = nullptr };
auto* socket = CFSocketCreateWithNative(kCFAllocatorDefault, notifier.fd(), notification_type, &socket_notifier, &context);
CFOptionFlags sockopt = CFSocketGetSocketFlags(socket);