mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 13:50:00 +00:00
AK: Expose helpers to invoke Windows runtime config directly in main()
When shutting down helper processes, PosixSocketHelper::close() in SocketWindows when trying to close the socket fd with WSANOTINITIALISED. This was due to us initiating WinSock2 during static initialization and presumably also not terminating WinSock2 properly. Similar to WinSock2 initiation, calling CRT during static initialization is considered dangerous given the CRT DLL itself may not yet be initialized. Because of the above, we move to perform this Windows-specific runtime setup/teardown calls into the main() functions.
This commit is contained in:
parent
643f0de422
commit
7683f1285f
Notes:
github-actions[bot]
2025-10-30 03:09:04 +00:00
Author: https://github.com/ayeteadoe
Commit: 7683f1285f
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5981
Reviewed-by: https://github.com/ADKaster ✅
Reviewed-by: https://github.com/R-Goc
Reviewed-by: https://github.com/sakgoyal
Reviewed-by: https://github.com/stasoid
4 changed files with 60 additions and 18 deletions
38
AK/Windows.h
38
AK/Windows.h
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2024, stasoid <stasoid@yahoo.com>
|
||||
* Copyright (c) 2025, ayeteadoe <ayeteadoe@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -9,6 +10,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/Platform.h>
|
||||
|
||||
#ifdef AK_OS_WINDOWS // needed for Swift
|
||||
|
|
@ -18,4 +20,40 @@
|
|||
# undef IN
|
||||
# pragma comment(lib, "ws2_32.lib")
|
||||
# include <io.h>
|
||||
# include <stdlib.h>
|
||||
|
||||
inline void initiate_wsa()
|
||||
{
|
||||
WSADATA wsa;
|
||||
WORD version = MAKEWORD(2, 2);
|
||||
int rc = WSAStartup(version, &wsa);
|
||||
VERIFY(rc == 0 && wsa.wVersion == version);
|
||||
}
|
||||
|
||||
inline void terminate_wsa()
|
||||
{
|
||||
int rc = WSACleanup();
|
||||
VERIFY(rc == 0);
|
||||
}
|
||||
|
||||
static void invalid_parameter_handler(wchar_t const*, wchar_t const*, wchar_t const*, unsigned int, uintptr_t)
|
||||
{
|
||||
}
|
||||
|
||||
inline void override_crt_invalid_parameter_handler()
|
||||
{
|
||||
// Make _get_osfhandle return -1 instead of crashing on invalid fd in release (debug still __debugbreak's)
|
||||
_set_invalid_parameter_handler(invalid_parameter_handler);
|
||||
}
|
||||
|
||||
inline void windows_init()
|
||||
{
|
||||
initiate_wsa();
|
||||
override_crt_invalid_parameter_handler();
|
||||
}
|
||||
|
||||
inline void windows_shutdown()
|
||||
{
|
||||
terminate_wsa();
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,24 +23,6 @@ namespace Core::System {
|
|||
|
||||
int windows_socketpair(SOCKET socks[2], int make_overlapped);
|
||||
|
||||
static void invalid_parameter_handler(wchar_t const*, wchar_t const*, wchar_t const*, unsigned int, uintptr_t)
|
||||
{
|
||||
}
|
||||
|
||||
static int init_crt_and_wsa()
|
||||
{
|
||||
WSADATA wsa;
|
||||
WORD version = MAKEWORD(2, 2);
|
||||
int rc = WSAStartup(version, &wsa);
|
||||
VERIFY(!rc && wsa.wVersion == version);
|
||||
|
||||
// Make _get_osfhandle return -1 instead of crashing on invalid fd in release (debug still __debugbreak's)
|
||||
_set_invalid_parameter_handler(invalid_parameter_handler);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static auto dummy = init_crt_and_wsa();
|
||||
|
||||
ErrorOr<int> open(StringView path, int options, mode_t mode)
|
||||
{
|
||||
ByteString str = path;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@
|
|||
#include <LibMain/Main.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#if defined(AK_OS_WINDOWS)
|
||||
# include <AK/Windows.h>
|
||||
#endif
|
||||
|
||||
namespace Main {
|
||||
|
||||
|
|
@ -31,6 +34,10 @@ int main(int argc, char** argv)
|
|||
{
|
||||
tzset();
|
||||
|
||||
#if defined(AK_OS_WINDOWS)
|
||||
windows_init();
|
||||
#endif
|
||||
|
||||
Vector<StringView> arguments;
|
||||
arguments.ensure_capacity(argc);
|
||||
for (int i = 0; i < argc; ++i)
|
||||
|
|
@ -41,6 +48,11 @@ int main(int argc, char** argv)
|
|||
.argv = argv,
|
||||
.strings = arguments.span(),
|
||||
});
|
||||
|
||||
#if defined(AK_OS_WINDOWS)
|
||||
windows_shutdown();
|
||||
#endif
|
||||
|
||||
if (result.is_error()) {
|
||||
auto error = result.release_error();
|
||||
warnln("\033[31;1mRuntime error\033[0m: {}", error);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@
|
|||
#include <AK/Format.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibTest/TestSuite.h>
|
||||
#if defined(AK_OS_WINDOWS)
|
||||
# include <AK/Windows.h>
|
||||
#endif
|
||||
|
||||
#define TEST_MAIN main
|
||||
|
||||
|
|
@ -18,6 +21,10 @@ int TEST_MAIN(int argc, char** argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#if defined(AK_OS_WINDOWS)
|
||||
windows_init();
|
||||
#endif
|
||||
|
||||
Vector<StringView> arguments;
|
||||
arguments.ensure_capacity(argc);
|
||||
for (auto i = 0; i < argc; ++i)
|
||||
|
|
@ -25,6 +32,9 @@ int TEST_MAIN(int argc, char** argv)
|
|||
|
||||
int ret = ::Test::TestSuite::the().main(argv[0], arguments);
|
||||
::Test::TestSuite::release();
|
||||
#if defined(AK_OS_WINDOWS)
|
||||
windows_shutdown();
|
||||
#endif
|
||||
// As TestSuite::main() returns the number of test cases that did not pass,
|
||||
// ret can be >=256 which cannot be returned as an exit status directly.
|
||||
// Return 0 if all of the test cases pass and return 1 otherwise.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue