On 2013-12-11 19:17, Ingo Walz wrote:
Hello modules-dev!

I've encountered a problem with an apr_hash_t in the global scope of my
module.
Let me explain the use-case a bit.

Every time, when an asset (image e.g.) is delivered via apache, it
stores meta information of that file with a simple key/value pair in an
apr_hash_t. That variable is part of the global scope of my module and
allocated in register_hooks section (with the pool available here). If
HTML is delivered that references an asset with meta information
available, it rewrites the HTML based on the data from apr_hash_t.

My problem is: using -X (only one worker) everything is fine and the
module works as expected. But starting httpd with more than one worker,
I sometime have no data on my apr_hash_t, which is expected to be there.
I've tried various things, e.g. using server->process->pool and
child_init to allocate the data, but the issue remains the same. I'm
also using no global/thread_mutex, because I'm never reading and writing
in the same thread (but in theory in the same process) - but I've no
idea yet how hash_set is doing it internally, so this might be still a
todo (is it? Do I really need a global mutex for data across
worker/threads? Can I avoid it?). Using memcache is an option in theory,
but I'd love to avoid it too. Otherwise my module scales much different,
based on the delivered HTML. But anyways, it's most likely an issue with
the "wrong pool" or with a misunderstanding of the scope and the cleanup
of those pools.

I'm making the assumption that you're using Unix and not Windows.

I don't think it is related to pools or their cleanup. It is rather because of how Unix processes work. The request that updates your hash is served by a thread in one apache child and the request that reads from your hash may be served by a thread in another apache child. The problem is that each apache child has its own copy of the hash.

What's the best way to use a "everywhere shared apr_hash_t"? Do I need
apr_shm to work properly with the workers (or apr_rmm in my use case)
together with a global_mutex or should I try to dig into socache and
avoid doing this handling manually? Many outdated resources around the
web (and even different internal implementations for the same use-case)
made me feel a bit ... doubtful to come to a final decision. Maybe you
can help me here?! :-)

My advice would be to avoid doing it manually.

Regards,
Sorin


Regards,

Ingo

Reply via email to