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
> 

Reply via email to