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
****** ***** **