apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Branko ─îibej <br...@apache.org>
Subject Re: [PATCH] deadlocking condition with APR_HAS_THREADS
Date Thu, 02 Feb 2017 11:52:32 GMT
On 01.02.2017 00:23, Stefan wrote:
> Hi,
> the issue was discovered as part of tracing down a deadlock condition in
> an SVN test [1].
> As far as I understand it, the problem lies in the C-standard not
> explicitly defining when a function registered with atexit() is called
> in the context of thread termination [2].
> The case is reproducible with the following code inside a DLL and
> executing that from a calling process (a complete repro project is
> available on my issue tracker [1]):
>     atexit(apr_terminate);
>     apr_initialize();
>     apr_pool_t *pool;
>     apr_pool_create_ex(&pool, NULL, NULL, NULL);
>     apr_thread_pool_t *thread_pool;
>     apr_thread_pool_create(&thread_pool, 0, 16, pool);
>     apr_thread_pool_idle_wait_set(thread_pool, 1000 * 1000);
>     for (int i = 0; i < 3; ++i) {
>       apr_thread_pool_push(thread_pool, foo, nullptr, 0, NULL);
>     }
> In this particular case we create a couple of threads and before the
> threads terminate the calling process terminates. At this point
> apr_terminate() is called which got registered via the atexit()-call (as
> suggested in the apr_terminate-documentation).

This is incorrect. apr_terminate() is not called after the calling
process terminates; that would make no sense at all: if there's no
process, it cannot execute any code.

Handlers registered with atexit() are called "when the program
terminates normally": either when exit() is called, or when main()
returns, and certainly _before_ the process terminates.

Windows' documentation of atexit has this to say about shared libraries:

    The code in the atexit function should not contain any dependency on
    any DLL which could have already been unloaded when the atexit
    function is called.

This is what might be happening, if Subversion is dynamically loading
the shared library that contains the thread pool code.

-- Brane

View raw message