After further experimentation, I have determined that the shared memory code 
does something unexpected (at least, to me).  I have multiple processes {A..E} 
that each ask for a block of memory using the apr_shm_create() call and convert 
it to a Node.  Each process requests the memory from the same pool and gets the 
block at the EXACT same address, say X.  After doing the apr_shm_baseaddr_get() 
each process can see the block, updates it, and adds the new node to an array.

After all five processes have obtained the node and updated the array, it has 
exactly one address in the first five array elements.  Therefore, every 
reference to the address after calling apr_shm_baseaddr_get() points to the 
particular node that the process created (demonstrated by the fact that its 
contents are the value the process set into it).  Upon the sixth attempt to 
create a Node, process A calls create and obtains a different address; the pool 
allocater knows that address X is already allocated to this process, so it 
allocates Y.  Then the next four processes do the same, each getting Y for the 
total of two unique node addresses after ten calls.

Log output:

[Tue Jan 26 10:50:09 2010] [error] [client 192.168.56.1] in log_transaction
[Tue Jan 26 10:50:09 2010] [error] [client 192.168.56.1] new node at 146435384 
by 5709
[Tue Jan 26 10:50:09 2010] [error] [client 192.168.56.1] node @ 146435384 is 1
[Tue Jan 26 10:50:12 2010] [error] [client 192.168.56.1] in log_transaction
[Tue Jan 26 10:50:12 2010] [error] [client 192.168.56.1] new node at 146435384 
by 5710
...
[Tue Jan 26 10:50:34 2010] [error] [client 192.168.56.1] in log_transaction
[Tue Jan 26 10:50:34 2010] [error] [client 192.168.56.1] new node at 146435432 
by 5709
[Tue Jan 26 10:50:34 2010] [error] [client 192.168.56.1] node @ 146435384 is 1
[Tue Jan 26 10:50:34 2010] [error] [client 192.168.56.1] node @ 146435384 is 1
[Tue Jan 26 10:50:34 2010] [error] [client 192.168.56.1] node @ 146435384 is 1
[Tue Jan 26 10:50:34 2010] [error] [client 192.168.56.1] node @ 146435384 is 1
[Tue Jan 26 10:50:34 2010] [error] [client 192.168.56.1] node @ 146435384 is 1
[Tue Jan 26 10:50:34 2010] [error] [client 192.168.56.1] node @ 146435432 is 6

Relevant code:

static int log_transaction(request_rec* request) {
     List*      list;
     Node*      node;

     ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request, "in log_transaction");
     list = (List*)apr_shm_baseaddr_get(shared_list);

     apr_shm_create(&(list->list[list->count]), sizeof(Node), NULL, list->pool);
     ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request, "new node at %ld by %ld", 
(long int)list->list[list->count], (long int)getpid());
     node = (Node*)apr_shm_baseaddr_get(list->list[list->count]);
     list->count++;
     node->number = list->count;

     for (int i = 0; i < list->count; i++) {
           node = (Node*)apr_shm_baseaddr_get(list->list[i]);
           ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request, "node @ %ld is %d", 
(long int)list->list[i], node->number);
     }
     return DECLINED;
}

Does anyone have an idea why a given pool will return the same address to each 
process?  The pool in question is the one passed to the post_config(apr_pool_t* 
pool, ...) function.  Would not it be expected that the pool would NEVER return 
the same block (unless destroyed first)?  Or, does this mean that the address 
of a shared memory block is determined both by a free block and a process id?  
If I understand the create call in apr_shm.c, mmap is what determines the 
address of the block.  Why would each process get the same value back from it, 
but the subsequent call by the same process correctly gets a different address?

Clearly I am missing something and have searched in vain to understand it.  All 
help is deeply appreciated (and obviously needed).

Thank you,

Rich Yonts
sola fide, sola gratia, solus Christus, sola Scriptura, soli Deo gloria
****** ***** **

Reply via email to