From: Jacek Caban <jacek@codeweavers.com> --- dlls/vcruntime140/Makefile.in | 1 + dlls/vcruntime140/init_thread.c | 83 +++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 dlls/vcruntime140/init_thread.c diff --git a/dlls/vcruntime140/Makefile.in b/dlls/vcruntime140/Makefile.in index 30231e1b074..a0004e52af6 100644 --- a/dlls/vcruntime140/Makefile.in +++ b/dlls/vcruntime140/Makefile.in @@ -2,6 +2,7 @@ MODULE = vcruntime140.dll IMPORTLIB = vcruntime140 SOURCES = \ + init_thread.c \ misc.c \ new.cpp \ typeinfo_root.cpp diff --git a/dlls/vcruntime140/init_thread.c b/dlls/vcruntime140/init_thread.c new file mode 100644 index 00000000000..6d73f85785f --- /dev/null +++ b/dlls/vcruntime140/init_thread.c @@ -0,0 +1,83 @@ +/* + * Thread-safe static constructor support functions. + * + * Copyright 2026 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep implib +#endif + +#ifdef __WINE_PE_BUILD + +#include <stdarg.h> +#include <limits.h> +#include "windef.h" +#include "winbase.h" + +static SRWLOCK init_lock; +static CONDITION_VARIABLE init_cv; + +int _Init_global_epoch = INT_MIN; +__thread int _Init_thread_epoch = INT_MIN; + +void _Init_thread_lock(void) +{ + AcquireSRWLockExclusive( &init_lock ); +} + +void _Init_thread_unlock(void) +{ + ReleaseSRWLockExclusive( &init_lock ); +} + +void _Init_thread_wait( DWORD timeout ) +{ + SleepConditionVariableSRW( &init_cv, &init_lock, timeout, 0 ); +} + +void _Init_thread_notify(void) +{ + WakeAllConditionVariable( &init_cv ); +} + +void _Init_thread_header( int *once ) +{ + _Init_thread_lock(); + while (*once == -1) _Init_thread_wait( INFINITE ); + if (*once) _Init_thread_epoch = _Init_global_epoch; + else *once = -1; + _Init_thread_unlock(); +} + +void _Init_thread_footer( int *once ) +{ + _Init_thread_lock(); + _Init_thread_epoch = *once = ++_Init_global_epoch; + _Init_thread_unlock(); + _Init_thread_notify(); +} + +void _Init_thread_abort( int *once ) +{ + _Init_thread_lock(); + *once = 0; + _Init_thread_unlock(); + _Init_thread_notify(); +} + +#endif -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10273