On Tuesday, November 19, 2002, at 09:49 PM, <[EMAIL PROTECTED]> wrote:
By allocating the mutex in the pool they have already stated that the pool
should control the mutex's scope. That is the meaning of allocating a
varibale inside a pool. This is why pools are passed to ALL functions.


BTW, you can't leave this up to the app. The abstraction layer makes it
too complex to have the app take care of this. I thought at first that
the app should just kill the cleanup, but that is too hard. If you make
the app register the cleanup, you will have code like:


if (mutex->type == (fcntl || flock)) {
    register_cleanup
else
    no-op

Why is that? Perhaps that means that apr_proc_mutex_t is the wrong abstraction for these types.

If you read ALL of those functions, they are all:

    if ((rv = proc_mutex_(.*)_cleanup(mutex)) == APR_SUCCESS) {
        apr_pool_cleanup_kill(mutex->pool, mutex, (.*)_sysv_cleanup);
        return APR_SUCCESS;
    }
    return rv;

which means that the cleanup as it is registered today is equivalent to
apr_proc_mutex_destroy. The functions that they call are equivalent. I
am making the change now to use a public function for the cleanup, because
anything else is completely bogus.

So there will have to be some internal changes (no critical interface changes)
to make this work. Fine, but what will this break anything else?


Let's talk about some use cases:

1) parent owns semaphore
children created and destroyed, after which parent destroys semaphore
2) parent creates semaphore and delegates ownership to a child
3) one process creates semaphore, another non-related process attaches to
the semaphore, a third takes responsibility for destroying it
...


To me it seems the only way to support all of these use cases would be
to allow the app to explicitly create and destroy their own semaphores
whenever they want without any magic cleanup handlers happen unexpectedly.


If you read my messages from earlier today, I have already answered all of
the questions that you posted in each of the 5 messages you just sent.
But one more time:


The parent process allocates the mutex out of whatever pool should control
the scope.

This is not in dispute. In testprocmutex, the mutex was created in the global
pool, and since the parent global pool lives longer than the children
(We call waitpid to synchronize the children) it was expected that the
mutex would live until the end. This was a false assumption.


The child processesmust call apr_proc_mutex_child_init. That function
defines the scope of the mutex for the child process. If the mutex type
requires a cleanup in the child process, then one is registered.

Again, not in dispute. This still needs to be added, btw.

As for the bug that was hit.  Programs _MUST_ have an equal number of
apr_initialize and apr_terminate calls.  If it doesn't, then bugs like
this will happen.

I'm glad we worked through and found this to be the problem, since it has shown me how broken this part of APR is. Could we solve this by having apr_proc_create() increment the global counter? Are there resources that will not be cleaned up in children if we always call ap_initialize() in child processes (eg. when a process dies on Windows, will it close all its files and sockets?)?

-aaron



Reply via email to