You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modules-dev@httpd.apache.org by Brian McQueen <mc...@gmail.com> on 2006/10/10 17:43:32 UTC

server config apr_table_t

I am having a problem with keeping data in my apr_table_t.  During a
request I obtain the server config structure, store something in there
(some statistics which should have the scope of the life of the
server), and then when the next request comes along, the data is gone!
 During the request I store it and retrieve it, just to make sure the
mechanism is correct with no problems, but when the request is gone,
the data is gone too.  Obviously it seems to be a request pool related
issue, but I tried to get around that by being very specific about
which pool to use.  I've made a sub-pool of the pool that created the
server config structure and saved that within the server config
structure.  I've also made sure the tables are "made" with this very
same pool.  What is happening to my data?  I've even created a brand
new root pool with the same results.  I'm using the apr_tables.h
techniques like this:

Here is how I'm initializing the table - here with a root pool:

ASSERT(apr_pool_create(&server_config_p->stats_pool, NULL) == APR_SUCCESS);

server_config_p->approved_items =
apr_table_make(server_config_p->stats_pool, 500);

Neither of these lasts beyond the request, not even the one with
static char strings:

apr_table_set(server_config.approved_items, my_key, my_value);
apr_table_set(server_config.approved_items, "key2", "value2");

During the request I can loop over the table with apr_table_do and
print out all of the data, but by the next request its all gone.

Brian McQueen

Re: server config apr_table_t

Posted by Nick Kew <ni...@webthing.com>.
On Wednesday 11 October 2006 00:55, David Wortham wrote:
> On 10/10/06, William A. Rowe, Jr. <wr...@rowe-clan.net> wrote:
> > You are responsible for mutexing; and remember unless you alloc before
> > fork and never modify the data, it's per-process private.
>
> Is this to say that using a subpool of a "s->process->pool" pool, what
> mutations made by one child process won't be seen by other child
> processes?

Yes (wrowe already replied to that).  Bear in mind that you have both
multiple processes and multiple threads to deal with.

> Right now, I have a module (based roughly off of mod_evasive 2.0 for
> website RBLing and caching of recent RBL lookups).  I'm using a file
> for caching, but I would like to have my lookups stored in
> parent-process memory so that each child process does not have to sync
> to the file and keep its own lookup hashtable.

My first thought on that task is to use something like dnscache,
rather than reinventing that wheel.  IIRC someone's done that already,
but I don't recollect the details.

-- 
Nick Kew

Application Development with Apache - the Apache Modules Book
http://www.prenhallprofessional.com/title/0132409674

Re: server config apr_table_t

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
David Wortham wrote:
> On 10/10/06, William A. Rowe, Jr. <wr...@rowe-clan.net> wrote:
>> You are responsible for mutexing; and remember unless you alloc before
>> fork and never modify the data, it's per-process private.
> 
> Is this to say that using a subpool of a "s->process->pool" pool, what
> mutations made by one child process won't be seen by other child
> processes?

All of them.  Understand that all malloc()ed memory heap pages in most
kernels are shared but marked copy-on-write.  As soon as any forked
process (every httpd child worker process) touches one byte in those
pages, they get their own copy of the memory that's then modified.

If you never write to pconf, then all child processes will continue to
share the same, single copy.  Until one writes to it, potentially
chewing up alot of memory if there are many processes and many small
changes in that pool.  That's why I say touching the global pools
such as pconf is just a bad idea.

So if you can't share palloc()'ed memory - what to do?  Use the apr_shm
or apr_mmap interfaces to create shared memory segments across processes.

> Right now, I have a module (based roughly off of mod_evasive 2.0 for
> website RBLing and caching of recent RBL lookups).  I'm using a file
> for caching, but I would like to have my lookups stored in
> parent-process memory so that each child process does not have to sync
> to the file and keep its own lookup hashtable.

gotcha

> BTW - I'm new to the mailiing list.  If I need to reformat or send
> replies in some other manner, please inform me.

Looks fine here

Re: server config apr_table_t

Posted by David Wortham <dj...@gmail.com>.
On 10/10/06, William A. Rowe, Jr. <wr...@rowe-clan.net> wrote:
> You are responsible for mutexing; and remember unless you alloc before fork
> and never modify the data, it's per-process private.

Is this to say that using a subpool of a "s->process->pool" pool, what
mutations made by one child process won't be seen by other child
processes?

Right now, I have a module (based roughly off of mod_evasive 2.0 for
website RBLing and caching of recent RBL lookups).  I'm using a file
for caching, but I would like to have my lookups stored in
parent-process memory so that each child process does not have to sync
to the file and keep its own lookup hashtable.

BTW - I'm new to the mailiing list.  If I need to reformat or send
replies in some other manner, please inform me.

Re: server config apr_table_t

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
Brian McQueen wrote:
> Here is how I'm initializing the table - here with a root pool:
> 
> ASSERT(apr_pool_create(&server_config_p->stats_pool, NULL) == APR_SUCCESS);


FYI - the config pool is *nonvolatile* - your approach blows up on threaded
MPM's and further it's just bad practice.

The pool you probably want for server process lifetime is s->process->pool.

You are responsible for mutexing; and remember unless you alloc before fork
and never modify the data, it's per-process private.  If you like, you can
create an mmap in the parent if your data is going to span the process, but
again you are responsible for crossthread/crossproc mutexing of that data.

Re: server config apr_table_t

Posted by Brian McQueen <mc...@gmail.com>.
I'm glad to see your book is now available!  I'll buy it right away.
Get your own copy now you guys!

http://www.prenhallprofessional.com/title/0132409674

On 10/10/06, Nick Kew <ni...@webthing.com> wrote:
> On Tuesday 10 October 2006 16:43, Brian McQueen wrote:
> > I am having a problem with keeping data in my apr_table_t.  During a
> > request I obtain the server config structure, store something in there
> > (some statistics which should have the scope of the life of the
> > server), and then when the next request comes along, the data is gone!
>
> The next request was handled by a different process.
>
> > Here is how I'm initializing the table - here with a root pool:
>
> The canonical way to create your pool would be to make a subpool
> of pchild in a child_init hook.
>
> > Neither of these lasts beyond the request, not even the one with
> > static char strings:
> >
> > apr_table_set(server_config.approved_items, my_key, my_value);
> > apr_table_set(server_config.approved_items, "key2", "value2");
>
> These should be done under mutex, fwiw.
>
> --
> Nick Kew
>
> Application Development with Apache - the Apache Modules Book
> http://www.prenhallprofessional.com/title/0132409674
>

Re: server config apr_table_t

Posted by Nick Kew <ni...@webthing.com>.
On Tuesday 10 October 2006 16:43, Brian McQueen wrote:
> I am having a problem with keeping data in my apr_table_t.  During a
> request I obtain the server config structure, store something in there
> (some statistics which should have the scope of the life of the
> server), and then when the next request comes along, the data is gone!

The next request was handled by a different process.

> Here is how I'm initializing the table - here with a root pool:

The canonical way to create your pool would be to make a subpool
of pchild in a child_init hook.

> Neither of these lasts beyond the request, not even the one with
> static char strings:
>
> apr_table_set(server_config.approved_items, my_key, my_value);
> apr_table_set(server_config.approved_items, "key2", "value2");

These should be done under mutex, fwiw.

-- 
Nick Kew

Application Development with Apache - the Apache Modules Book
http://www.prenhallprofessional.com/title/0132409674