Hi Ralf,
thanks for the explaination. As i see - i can't use a simple pointer
and after reading your answer it's clear why! So it's not that easy
to store dynamic content (like arrays) into a shared memory segment.
Actually i have looked at the ldap-caching functions from mod_ldap.
They do something similar as i wanted to do and it seems to me that
a lot of more work has to be done to make it work correctly.
Sorry for this stupid question. Ticket closed.
Greetings
Michael
On Mon, 2011-11-14 at 16:42 +0100, rm@tuxteam.de wrote:
> On Mon, Nov 14, 2011 at 02:18:20PM +0100, michaelr wrote:
> > Hi all,
> >
> > first excuse my bad english. As a beginner in apache module development
> > i have a problem understanding the apr shared memeory handling. In the
> > following example i removed all the locks and error handling to bring my
> > problem in front. Even the malloc and free calls are only for testing
> > purposes (in a real module i will use memory pools).
> >
> > As an example i have the following struct defined in my header:
> >
> > typedef struct
> > {
> > unsigned int active ;
> > char *test ;
> > } shm_seg_t ;
> >
>
> That char pointer smells funky!
>
> [...]
> > // malloc just for testing purposes!
> > acl_pool->test = (char *) malloc ( 40 * sizeof(char) );
>
> And here is why: acl_pool->test will now point to an address on
> the current process' heap. That's just a number with no relevance
> to other processes.
>
> > strcpy(acl_pool->test, "POSTCONFIGHANDLER");
> > fprintf(stderr," post: --> %s\n", acl_pool->test);
> > fflush(stderr);
>
> Yes, because you read from your own memory.
>
> >
> > This works. So in the module handler i can access the varaibles
> > like this:
> >
> > apr_shm_attach(&acl_pool_shm, "/tmp/file", r->pool) ;
> > acl_pool = (shm_seg_t *) apr_shm_baseaddr_get(acl_pool_shm) ;
> >
> > printf(stderr, " HANDLER: --> %d - %s\n",
> > acl_pool->active, acl_pool->test) ;
> > fflush(stderr) ;
> >
> >
> > Everything is fine until here - it prints out:
> >
> > HANDLER: --> 0 - POSTCONFIGHANDLER
> >
> > to the error log.
> >
> >
> > I want to update the data in the shared memeory segement in an
> > monitor_hook which i set up also. In the monitor_hook i do the
> > following:
> >
> > apr_shm_attach(&acl_pool_shm, "/tmp/file", p) ;
> >
> > acl_pool = (shm_seg_t *) apr_shm_baseaddr_get(acl_pool_shm) ;
> >
> > acl_pool->active++ ;
> >
> > if ( acl_pool->test != NULL)
> > {
> > free(acl_pool->test) ;
>
> Kawoom! You just handed free a number that has only meaning within
> the context of the process that did _set_ this number.
> There's no magic to get your hands on another processes memory (at least
> not since Mac Os7 and OS/2 left this planet).
>
> > acl_pool->test = (char *) malloc(40 * sizeof(char)) ;
> > strcpy(acl_pool->test, "SCHEDULER") ;
> > fprintf(stderr, " scheduler: --> %s\n", acl_pool->test) ;
> > fflush(stderr) ;
> > }
> >
> >
> > Now i run into the problem that the module_handler did'nt recognise
> > the changes i have made so far in the monitor_hook. acl_pool->test
> > did not change in the child process and it always prints out:
> >
> > HANDLER: --> 1 - POSTCONFIGHANDLER
> > HANDLER: --> 2 - POSTCONFIGHANDLER
> > HANDLER: --> 3 - POSTCONFIGHANDLER
> >
> > The integer varaibles get incremented as expected. The dynamic
> > variable: char *test did'nt change at all. I set MaxRequestsPerChild
> > to zero in this first try.
>
> Yes, acl_pool->active is a storage location, i.e. the value get's stored
> and read from shared memory, but acl_pool->test is only a _pointer_ to a
> storage location local to one process.
>
> > When i set MaxRequestsPerChild to 4 for something else below and the
> > childs get restarted by the root-Server the next call to the
> > module-handler prints out:
> >
> > HANDLER: --> 1 - SCHEDULER
>
> Here you most likely happen to get the request served from the same
> process where acl_pool->test _happens_ to point to the right location
> ...
>
> > So my questions is: Why i can not see the changes which the
> > monitor hook has done until the childs gets restarted? The integer
> > variable is readable with the correct update at any time.
>
> You would have to allocate the character data from shared memory, but
> keep in mind that even then a simple pointer wouldn't work (since one
> location in shared memory can and will have different addresses in
> different processes). A bit of googling will bring you further material
> (this has been discussed in this mailing list abd elsewhere).
>
> HTH Ralf Mattes
>
> > Thank's for your help.
> >
> > Greetings Michael
> >
|