Hi,
Someone in the Subversion team made our C tests run in parallel. With that
our buildbot found a race condition in the Windows specific
APR_DECLARE_LATE_DLL_FUNC() implementation.
The current code is
[[
#define APR_DECLARE_LATE_DLL_FUNC(lib, rettype, calltype, fn, ord, args,
names) \
typedef rettype (calltype *apr_winapi_fpt_##fn) args; \
static apr_winapi_fpt_##fn apr_winapi_pfn_##fn = NULL; \
static int apr_winapi_chk_##fn = 0; \
static APR_INLINE int apr_winapi_ld_##fn(void) \
{ if (apr_winapi_pfn_##fn) return 1; \
if (apr_winapi_chk_##fn ++) return 0; \
if (!apr_winapi_pfn_##fn) \
apr_winapi_pfn_##fn = (apr_winapi_fpt_##fn) \
apr_load_dll_func(lib, #fn, ord); \
if (apr_winapi_pfn_##fn) return 1; else return 0; }; \
static APR_INLINE rettype apr_winapi_##fn args \
{ if (apr_winapi_ld_##fn()) \
return (*(apr_winapi_pfn_##fn)) names; \
else { SetLastError(ERROR_INVALID_FUNCTION); return 0;} }; \
#define APR_HAVE_LATE_DLL_FUNC(fn) apr_winapi_ld_##fn()
]]
(I can reproduce the problem locally)
The ++ on the second line of the function body makes calls in other threads
skip the initialization, which may cause them to see no function (or
theoretically a bad pointer).
I think the dll load function should be converted to a more stable pattern,
that properly handles multiple threads. And perhaps we should just assume a
few more NT functions to be alsways there instead of loading them
dynamically.
Bert
Received on 2013-12-05 15:01:45 CET