summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorivan <ivan@13f79535-47bb-0310-9956-ffa450edef68>2019-05-20 15:06:28 +0000
committerivan <ivan@13f79535-47bb-0310-9956-ffa450edef68>2019-05-20 15:06:28 +0000
commitaed1dfa871df9a87c7067c2b88c51182e6fc9181 (patch)
tree4c1f16dc325546719defc9c2e94c0a799df7bd23
parent6e7404ff7cae37e304a3dcbc8a983db3d84dbe16 (diff)
downloadlibapr-aed1dfa871df9a87c7067c2b88c51182e6fc9181.tar.gz
On 'xmllite' branch: Merge changes from trunk.
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/branches/xmllite@1859568 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES6
-rw-r--r--CMakeLists.txt6
-rw-r--r--dso/win32/dso.c84
-rw-r--r--file_io/win32/dir.c16
-rw-r--r--file_io/win32/pipe.c10
-rw-r--r--file_io/win32/seek.c47
-rw-r--r--include/apr.hw2
-rw-r--r--include/arch/win32/apr_arch_misc.h29
-rw-r--r--include/arch/win32/apr_arch_threadproc.h2
-rw-r--r--misc/win32/misc.c55
-rw-r--r--misc/win32/start.c2
-rw-r--r--shmem/win32/shm.c8
-rw-r--r--test/testbuckets.c2
-rw-r--r--threadproc/win32/thread.c28
-rw-r--r--threadproc/win32/threadpriv.c2
15 files changed, 151 insertions, 148 deletions
diff --git a/CHANGES b/CHANGES
index 18dc42dec..0ba7700de 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,12 @@
-*- coding: utf-8 -*-
Changes for APR 2.0.0
+ *) apr_thread_once: Fix problem that apr_thread_once can return before
+ the other thread completes initialization on Windows.
+
+ *) Windows platform: Remove support for Windows 2000, XP, Vista. The minimum
+ supported OS versions are now Windows 7 / Windows Server 2008 R2.
+
*) apr_file_info: [Win32 only] Treat only "name surrogate" reparse points
as symlinks, and not other reparse tag types. PR47630
[Oleg Liatte <olegliatte gmail.com>]
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 68b9ca26a..004452d6b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -55,7 +55,7 @@ OPTION(APR_HAVE_IPV6 "IPv6 support" ON)
OPTION(INSTALL_PDB "Install .pdb files (if generated)" ON)
OPTION(APR_BUILD_TESTAPR "Build the test suite" OFF)
OPTION(TEST_STATIC_LIBS "Test programs use APR static libraries instead of shared libraries?" OFF)
-SET(MIN_WINDOWS_VER "Vista"
+SET(MIN_WINDOWS_VER "Windows7"
CACHE STRING "Minimum Windows version")
SET(LIBXML2_ICONV_INCLUDE_DIR ""
CACHE STRING "Directory with iconv include files for libxml2")
@@ -100,9 +100,9 @@ ELSE(APU_USE_XMLLITE)
ENDIF()
IF("${MIN_WINDOWS_VER}" STREQUAL "")
- SET(win32_winnt_str "0x0600")
+ SET(win32_winnt_str "0x0601")
ELSEIF(${MIN_WINDOWS_VER} STREQUAL "Vista")
- SET(win32_winnt_str "0x0600")
+ MESSAGE(FATAL_ERROR "Minimum supported Windows version is Windows 7/Windows Server 2008 R2")
ELSEIF(${MIN_WINDOWS_VER} STREQUAL "Windows7")
SET(win32_winnt_str "0x0601")
ELSE()
diff --git a/dso/win32/dso.c b/dso/win32/dso.c
index 89885e5fa..9681d91b5 100644
--- a/dso/win32/dso.c
+++ b/dso/win32/dso.c
@@ -60,71 +60,37 @@ APR_DECLARE(apr_status_t) apr_dso_load(struct apr_dso_handle_t **res_handle,
UINT em;
#endif
-#if APR_HAS_UNICODE_FS
- IF_WIN_OS_IS_UNICODE
- {
- apr_wchar_t wpath[APR_PATH_MAX];
- if ((rv = utf8_to_unicode_path(wpath, sizeof(wpath)
- / sizeof(apr_wchar_t), path))
- != APR_SUCCESS) {
- *res_handle = apr_pcalloc(ctx, sizeof(**res_handle));
- return ((*res_handle)->load_error = rv);
- }
- /* Prevent ugly popups from killing our app */
+ apr_wchar_t wpath[APR_PATH_MAX];
+ if ((rv = utf8_to_unicode_path(wpath, sizeof(wpath)
+ / sizeof(apr_wchar_t), path))
+ != APR_SUCCESS) {
+ *res_handle = apr_pcalloc(ctx, sizeof(**res_handle));
+ return ((*res_handle)->load_error = rv);
+ }
+ /* Prevent ugly popups from killing our app */
#ifndef _WIN32_WCE
- em = SetErrorMode(SEM_FAILCRITICALERRORS);
+ if (!SetThreadErrorMode(SEM_FAILCRITICALERRORS, &em)) {
+ *res_handle = apr_pcalloc(ctx, sizeof(**res_handle));
+ return ((*res_handle)->load_error = apr_get_os_error());
+ }
#endif
- os_handle = LoadLibraryExW(wpath, NULL, 0);
- if (!os_handle)
- os_handle = LoadLibraryExW(wpath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
- if (!os_handle) {
+ os_handle = LoadLibraryExW(wpath, NULL, 0);
+ if (!os_handle)
+ os_handle = LoadLibraryExW(wpath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+ if (!os_handle) {
#ifndef _WIN32_WCE
- apr_wchar_t *ignored;
- apr_wchar_t fpath[APR_PATH_MAX];
- rv = apr_get_os_error();
- if (GetFullPathNameW(wpath, sizeof(fpath) / sizeof(apr_wchar_t), fpath, &ignored)) {
- if (SetDllDirectoryW(fpath)) {
- os_handle = LoadLibraryExW(wpath, NULL, 0);
- if (!os_handle)
- os_handle = LoadLibraryExW(wpath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
- if (os_handle)
- rv = APR_SUCCESS;
- }
- }
-#else
- rv = apr_get_os_error();
-#endif
+ rv = apr_get_os_error();
+
+ os_handle = LoadLibraryExW(wpath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
+ if (os_handle) {
+ rv = APR_SUCCESS;
}
-#ifndef _WIN32_WCE
- SetErrorMode(em);
+#else
+ rv = apr_get_os_error();
#endif
}
-#endif /* APR_HAS_UNICODE_FS */
-#if APR_HAS_ANSI_FS
- ELSE_WIN_OS_IS_ANSI
- {
- char fspec[APR_PATH_MAX], *p = fspec;
- /* Must convert path from / to \ notation.
- * Per PR2555, the LoadLibraryEx function is very picky about slashes.
- * Debugging on NT 4 SP 6a reveals First Chance Exception within NTDLL.
- * LoadLibrary in the MS PSDK also reveals that it -explicitly- states
- * that backslashes must be used for the LoadLibrary family of calls.
- */
- apr_cpystrn(fspec, path, sizeof(fspec));
- while ((p = strchr(p, '/')) != NULL)
- *p = '\\';
-
- /* Prevent ugly popups from killing our app */
- em = SetErrorMode(SEM_FAILCRITICALERRORS);
- os_handle = LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
- if (!os_handle)
- os_handle = LoadLibraryEx(path, NULL, 0);
- if (!os_handle)
- rv = apr_get_os_error();
- else
- rv = APR_SUCCESS;
- SetErrorMode(em);
- }
+#ifndef _WIN32_WCE
+ SetThreadErrorMode(em, NULL);
#endif
*res_handle = apr_pcalloc(ctx, sizeof(**res_handle));
diff --git a/file_io/win32/dir.c b/file_io/win32/dir.c
index 8c8b74546..e4e3f7c73 100644
--- a/file_io/win32/dir.c
+++ b/file_io/win32/dir.c
@@ -128,6 +128,8 @@ APR_DECLARE(apr_status_t) apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
if (thedir->dirhand == INVALID_HANDLE_VALUE)
{
apr_status_t rv;
+ FINDEX_INFO_LEVELS info_level;
+
if ((rv = utf8_to_unicode_path(wdirname, sizeof(wdirname)
/ sizeof(apr_wchar_t),
thedir->dirname))) {
@@ -136,7 +138,19 @@ APR_DECLARE(apr_status_t) apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
eos = wcschr(wdirname, '\0');
eos[0] = '*';
eos[1] = '\0';
- thedir->dirhand = FindFirstFileW(wdirname, thedir->w.entry);
+
+ /* Do not request short file names on Windows 7 and later. */
+ if (apr_os_level >= APR_WIN_7) {
+ info_level = FindExInfoBasic;
+ }
+ else {
+ info_level = FindExInfoStandard;
+ }
+
+ thedir->dirhand = FindFirstFileExW(wdirname, info_level,
+ thedir->w.entry,
+ FindExSearchNameMatch, NULL,
+ 0);
eos[0] = '\0';
if (thedir->dirhand == INVALID_HANDLE_VALUE) {
return apr_get_os_error();
diff --git a/file_io/win32/pipe.c b/file_io/win32/pipe.c
index 601458258..b13507a91 100644
--- a/file_io/win32/pipe.c
+++ b/file_io/win32/pipe.c
@@ -120,6 +120,7 @@ static apr_status_t file_pipe_create(apr_file_t **in,
(void) apr_pollset_create(&(*out)->pollset, 1, p, 0);
#endif
if (apr_os_level >= APR_WIN_NT) {
+ apr_status_t rv;
char rand[8];
int pid = getpid();
#define FMT_PIPE_NAME "\\\\.\\pipe\\apr-pipe-%x.%lx."
@@ -150,7 +151,12 @@ static apr_status_t file_pipe_create(apr_file_t **in,
}
dwPipeMode = 0;
- apr_generate_random_bytes(rand, sizeof rand);
+ rv = apr_generate_random_bytes(rand, sizeof rand);
+ if (rv != APR_SUCCESS) {
+ file_cleanup(*in);
+ return rv;
+ }
+
pos = apr_snprintf(name, sizeof name, FMT_PIPE_NAME, pid, id++);
apr_escape_hex(name + pos, rand, sizeof rand, 0, NULL);
@@ -163,7 +169,7 @@ static apr_status_t file_pipe_create(apr_file_t **in,
1, /* nDefaultTimeOut, */
&sa);
if ((*in)->filehand == INVALID_HANDLE_VALUE) {
- apr_status_t rv = apr_get_os_error();
+ rv = apr_get_os_error();
file_cleanup(*in);
return rv;
}
diff --git a/file_io/win32/seek.c b/file_io/win32/seek.c
index dfef57716..673c6f578 100644
--- a/file_io/win32/seek.c
+++ b/file_io/win32/seek.c
@@ -23,7 +23,6 @@ static apr_status_t setptr(apr_file_t *thefile, apr_off_t pos )
{
apr_off_t newbufpos;
apr_status_t rv;
- DWORD rc;
if (thefile->direction == 1) {
/* XXX: flush here is not mutex protected */
@@ -43,19 +42,15 @@ static apr_status_t setptr(apr_file_t *thefile, apr_off_t pos )
thefile->bufpos = (apr_size_t)newbufpos;
rv = APR_SUCCESS;
} else {
- DWORD offlo = (DWORD)pos;
- LONG offhi = (LONG)(pos >> 32);
- rc = SetFilePointer(thefile->filehand, offlo, &offhi, FILE_BEGIN);
-
- if (rc == (DWORD)-1)
- /* A legal value, perhaps? MSDN implies prior SetLastError isn't
- * needed, googling for SetLastError SetFilePointer seems
- * to confirm this. INVALID_SET_FILE_POINTER is too recently
- * added for us to rely on it as a constant.
- */
+ LARGE_INTEGER li;
+ li.QuadPart = pos;
+
+ if (!SetFilePointerEx(thefile->filehand, li, NULL, FILE_BEGIN)) {
rv = apr_get_os_error();
- else
+ }
+ else {
rv = APR_SUCCESS;
+ }
if (rv == APR_SUCCESS) {
rv = APR_SUCCESS;
@@ -127,8 +122,8 @@ APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile, apr_seek_where_t wh
}
else {
DWORD howmove;
- DWORD offlo = (DWORD)*offset;
- DWORD offhi = (DWORD)(*offset >> 32);
+ LARGE_INTEGER li;
+ li.QuadPart = *offset;
switch(where) {
case APR_SET:
@@ -140,15 +135,17 @@ APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile, apr_seek_where_t wh
default:
return APR_EINVAL;
}
- offlo = SetFilePointer(thefile->filehand, (LONG)offlo,
- (LONG*)&offhi, howmove);
- if (offlo == 0xFFFFFFFF)
+
+ if (!SetFilePointerEx(thefile->filehand, li, &li, howmove)) {
rc = apr_get_os_error();
- else
+ }
+ else {
rc = APR_SUCCESS;
+ }
+
/* Since we can land at 0xffffffff we will measure our APR_SUCCESS */
if (rc == APR_SUCCESS)
- *offset = ((apr_off_t)offhi << 32) | offlo;
+ *offset = li.QuadPart;
return rc;
}
}
@@ -157,9 +154,7 @@ APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile, apr_seek_where_t wh
APR_DECLARE(apr_status_t) apr_file_trunc(apr_file_t *thefile, apr_off_t offset)
{
apr_status_t rv;
- DWORD offlo = (DWORD)offset;
- LONG offhi = (LONG)(offset >> 32);
- DWORD rc;
+ LARGE_INTEGER li;
if (thefile->buffered) {
if (thefile->direction == 1) {
@@ -188,10 +183,10 @@ APR_DECLARE(apr_status_t) apr_file_trunc(apr_file_t *thefile, apr_off_t offset)
}
}
- rc = SetFilePointer(thefile->filehand, offlo, &offhi, FILE_BEGIN);
- if (rc == 0xFFFFFFFF)
- if ((rv = apr_get_os_error()) != APR_SUCCESS)
- return rv;
+ li.QuadPart = offset;
+ if (!SetFilePointerEx(thefile->filehand, li, NULL, FILE_BEGIN))
+ return apr_get_os_error();
+
thefile->filePtr = offset;
/* Don't report EOF until the next read. */
thefile->eof_hit = 0;
diff --git a/include/apr.hw b/include/apr.hw
index 4d74d2f91..838335400 100644
--- a/include/apr.hw
+++ b/include/apr.hw
@@ -191,7 +191,7 @@
#endif
#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
+#define _WIN32_WINNT 0x0601
#endif
#ifndef NOUSER
diff --git a/include/arch/win32/apr_arch_misc.h b/include/arch/win32/apr_arch_misc.h
index b872b6ce5..2cf1c6545 100644
--- a/include/arch/win32/apr_arch_misc.h
+++ b/include/arch/win32/apr_arch_misc.h
@@ -230,27 +230,6 @@ FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char *fnName, int ordinal);
* these we must always look up
*/
-#ifdef GetCompressedFileSizeA
-#undef GetCompressedFileSizeA
-#endif
-APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, DWORD, WINAPI, GetCompressedFileSizeA, 0, (
- IN LPCSTR lpFileName,
- OUT LPDWORD lpFileSizeHigh),
- (lpFileName, lpFileSizeHigh));
-#define GetCompressedFileSizeA apr_winapi_GetCompressedFileSizeA
-#undef GetCompressedFileSize
-#define GetCompressedFileSize apr_winapi_GetCompressedFileSizeA
-
-#ifdef GetCompressedFileSizeW
-#undef GetCompressedFileSizeW
-#endif
-APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, DWORD, WINAPI, GetCompressedFileSizeW, 0, (
- IN LPCWSTR lpFileName,
- OUT LPDWORD lpFileSizeHigh),
- (lpFileName, lpFileSizeHigh));
-#define GetCompressedFileSizeW apr_winapi_GetCompressedFileSizeW
-
-
APR_DECLARE_LATE_DLL_FUNC(DLL_NTDLL, LONG, WINAPI, NtQueryTimerResolution, 0, (
ULONG *pMaxRes, /* Minimum NS Resolution */
ULONG *pMinRes, /* Maximum NS Resolution */
@@ -353,14 +332,6 @@ APR_DECLARE_LATE_DLL_FUNC(DLL_WINSOCK2API, int, WSAAPI, WSAPoll, 0, (
#define WSAPoll apr_winapi_WSAPoll
#define HAVE_POLL 1
-#ifdef SetDllDirectoryW
-#undef SetDllDirectoryW
-#endif
-APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, SetDllDirectoryW, 0, (
- IN LPCWSTR lpPathName),
- (lpPathName));
-#define SetDllDirectoryW apr_winapi_SetDllDirectoryW
-
#ifdef if_nametoindex
#undef if_nametoindex
#endif
diff --git a/include/arch/win32/apr_arch_threadproc.h b/include/arch/win32/apr_arch_threadproc.h
index d3ce9c518..9aee660fd 100644
--- a/include/arch/win32/apr_arch_threadproc.h
+++ b/include/arch/win32/apr_arch_threadproc.h
@@ -65,7 +65,7 @@ struct apr_procattr_t {
};
struct apr_thread_once_t {
- long value;
+ INIT_ONCE once;
};
extern apr_status_t apr_threadproc_init(apr_pool_t *pool);
diff --git a/misc/win32/misc.c b/misc/win32/misc.c
index 7a80f4fe9..b6ee202b0 100644
--- a/misc/win32/misc.c
+++ b/misc/win32/misc.c
@@ -138,32 +138,53 @@ apr_status_t apr_get_oslevel(apr_oslevel_e *level)
* missing from one or more releases of the Win32 API
*/
-static const char* const lateDllName[DLL_defined] = {
- "kernel32", "advapi32", "mswsock", "ws2_32", "shell32", "ntdll.dll",
- "Iphplapi" };
-static HMODULE lateDllHandle[DLL_defined] = {
- NULL, NULL, NULL, NULL, NULL, NULL,
- NULL };
+typedef struct win32_late_dll_t {
+ INIT_ONCE control;
+ const apr_wchar_t *dll_name;
+ HMODULE dll_handle;
+} win32_late_dll_t;
+
+static win32_late_dll_t late_dll[DLL_defined] = {
+ {INIT_ONCE_STATIC_INIT, L"kernel32", NULL},
+ {INIT_ONCE_STATIC_INIT, L"advapi32", NULL},
+ {INIT_ONCE_STATIC_INIT, L"mswsock", NULL},
+ {INIT_ONCE_STATIC_INIT, L"ws2_32", NULL},
+ {INIT_ONCE_STATIC_INIT, L"shell32", NULL},
+ {INIT_ONCE_STATIC_INIT, L"ntdll.dll", NULL},
+ {INIT_ONCE_STATIC_INIT, L"Iphplapi", NULL}
+};
+
+static BOOL WINAPI load_dll_callback(PINIT_ONCE InitOnce,
+ PVOID Parameter,
+ PVOID *Context)
+{
+ win32_late_dll_t *dll = Parameter;
+
+ dll->dll_handle = LoadLibraryW(dll->dll_name);
+
+ return TRUE;
+}
FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char* fnName, int ordinal)
{
- if (!lateDllHandle[fnLib]) {
- lateDllHandle[fnLib] = LoadLibraryA(lateDllName[fnLib]);
- if (!lateDllHandle[fnLib])
- return NULL;
- }
+ win32_late_dll_t *dll = &late_dll[fnLib];
+
+ InitOnceExecuteOnce(&dll->control, load_dll_callback, dll, NULL);
+ if (!dll->dll_handle)
+ return NULL;
+
#if defined(_WIN32_WCE)
if (ordinal)
- return GetProcAddressA(lateDllHandle[fnLib], (const char *)
- (apr_ssize_t)ordinal);
+ return GetProcAddressA(dll->dll_handle,
+ (const char *) (apr_ssize_t)ordinal);
else
- return GetProcAddressA(lateDllHandle[fnLib], fnName);
+ return GetProcAddressA(dll->dll_handle, fnName);
#else
if (ordinal)
- return GetProcAddress(lateDllHandle[fnLib], (const char *)
- (apr_ssize_t)ordinal);
+ return GetProcAddress(dll->dll_handle,
+ (const char *) (apr_ssize_t)ordinal);
else
- return GetProcAddress(lateDllHandle[fnLib], fnName);
+ return GetProcAddress(dll->dll_handle, fnName);
#endif
}
diff --git a/misc/win32/start.c b/misc/win32/start.c
index 2d7b5ff8f..ea8b964ac 100644
--- a/misc/win32/start.c
+++ b/misc/win32/start.c
@@ -127,7 +127,7 @@ APR_DECLARE(apr_status_t) apr_app_initialize(int *argc,
wstrs = CommandLineToArgvW(sysstr, &wstrc);
if (wstrs) {
*argc = apr_wastrtoastr(argv, wstrs, wstrc);
- GlobalFree(wstrs);
+ LocalFree(wstrs);
}
}
diff --git a/shmem/win32/shm.c b/shmem/win32/shm.c
index b01411ebd..0ca8247f9 100644
--- a/shmem/win32/shm.c
+++ b/shmem/win32/shm.c
@@ -87,10 +87,12 @@ static int can_create_global_maps(void)
ok = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
}
- if (ok) {
- ok = LookupPrivilegeValue(NULL, SE_CREATE_GLOBAL_NAME, &priv_id);
+ if (!ok) {
+ return 0;
}
+ ok = LookupPrivilegeValue(NULL, SE_CREATE_GLOBAL_NAME, &priv_id);
+
if (ok) {
privs.PrivilegeCount = 1;
privs.Control = PRIVILEGE_SET_ALL_NECESSARY;
@@ -99,6 +101,8 @@ static int can_create_global_maps(void)
ok = PrivilegeCheck(hToken, &privs, &has_priv);
}
+ CloseHandle(hToken);
+
if (ok && !has_priv) {
return 0;
}
diff --git a/test/testbuckets.c b/test/testbuckets.c
index 077a13936..31bed0c1b 100644
--- a/test/testbuckets.c
+++ b/test/testbuckets.c
@@ -105,7 +105,7 @@ static void flatten_match(abts_case *tc, const char *ctx,
sprintf(msg, "%s: length match (%ld not %ld)", ctx,
(long)len, (long)elen);
ABTS_ASSERT(tc, msg, len == elen);
- sprintf(msg, "%s: result match", msg);
+ sprintf(msg, "%s: result match", ctx);
ABTS_STR_NEQUAL(tc, expect, buf, len);
free(buf);
}
diff --git a/threadproc/win32/thread.c b/threadproc/win32/thread.c
index c713e1444..3204a1c2c 100644
--- a/threadproc/win32/thread.c
+++ b/threadproc/win32/thread.c
@@ -257,19 +257,39 @@ APR_DECLARE(apr_status_t) apr_os_thread_put(apr_thread_t **thd,
return APR_SUCCESS;
}
-APR_DECLARE(apr_status_t) apr_thread_once_init(apr_thread_once_t **control,
+APR_DECLARE(apr_status_t) apr_thread_once_init(apr_thread_once_t **control_p,
apr_pool_t *p)
{
- (*control) = apr_pcalloc(p, sizeof(**control));
+ apr_thread_once_t *control = apr_pcalloc(p, sizeof(*control));
+
+ InitOnceInitialize(&control->once);
+
+ *control_p = control;
+
return APR_SUCCESS;
}
+static BOOL WINAPI init_once_callback(PINIT_ONCE InitOnce,
+ PVOID Parameter,
+ PVOID *Context)
+{
+ void (*func)(void) = Parameter;
+
+ func();
+
+ return TRUE;
+}
+
APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control,
void (*func)(void))
{
- if (!InterlockedExchange(&control->value, 1)) {
- func();
+ PVOID lpContext;
+
+ if (!InitOnceExecuteOnce(&control->once, init_once_callback, func,
+ &lpContext)) {
+ return apr_get_os_error();
}
+
return APR_SUCCESS;
}
diff --git a/threadproc/win32/threadpriv.c b/threadproc/win32/threadpriv.c
index 787c142c4..1cce0c667 100644
--- a/threadproc/win32/threadpriv.c
+++ b/threadproc/win32/threadpriv.c
@@ -32,7 +32,7 @@ APR_DECLARE(apr_status_t) apr_threadkey_private_create(apr_threadkey_t **key,
(*key)->pool = pool;
- if (((*key)->key = TlsAlloc()) != 0xFFFFFFFF) {
+ if (((*key)->key = TlsAlloc()) != TLS_OUT_OF_INDEXES) {
return APR_SUCCESS;
}
return apr_get_os_error();