Hi,
I'm engaged in development of application (original module) upon apache 2.0
with mod_proxy, mpm_worker, etc on Solaris platform. I have a few question
related to connection->pool in mpm worker.
I had believed that the lifetime of each connection pool (the pool tagged
"transaction" and often referred as (request_rec*)r->conn->pool) is
basically same as a lifetime of TCP connection with peer. But recently I
found that the pool is not destructed at the end of connection and it is
reused for upcoming connection, in mpm worker. So the connection pools are
persistent, as long as the process lives.
(As far as I know, it same on the latest apache 2.2 and mpm worker)
It would not be a problem if we were using simply apache + mod_proxy +
mpm_worker, but it would cause a problem in the case that some additional
module (like ours) is used and it allocates rather large memory for some
reason with apr_allocator_alloc() on the connection pool. If the programmer
believes the lifetime of the pool is same as TCP connection, the size of
pool could drastically grow as the following scenario shows (assume single
worker thread for simplification):
1-1. The first request is coming.
1-2. The mod_XYZ allocates 100MB with apr_allocator_alloc() on connection
pool.
A memory block is allocated with malloc().
1-3. Then the mod_XYZ frees the above 100MB memory block with
apr_allocator_free().
The memory block is added into [connection pool]->allocator->free[0].
1-4. Connection with client is closed.
2-1. The second request is coming.
2-2. The mod_XYZ allocates 99MB with apr_allocator_alloc() on connection
pool.
The 100MB memory block pooled as [connection
pool]->allocator->free[0] is
leased for this memory request.
2-3. Then the mod_XYZ frees the above 100MB memory block with
apr_allocator_free().
The memory block is added into [connection pool]->allocator->free[0]
again.
2-4. Connection with client is closed.
3-1. The third request is coming.
3-2. The mod_XYZ allocates 101MB with apr_allocator_alloc() on connection
pool.
A memory block is allocated with malloc().
3-3. Then the mod_XYZ frees the above 101MB memory block with
apr_allocator_free().
The memory block is added into [connection pool]->allocator->free[0].
There are 100MB and 101MB blocks.
3-4. Connection with client is closed.
4-1. The next request is coming.
4-2. The mod_XYZ allocates 102MB with apr_allocator_alloc() on connection
pool.
A memory block is allocated with malloc().
4-3. Then the mod_XYZ frees the above 102MB memory block with
apr_allocator_free().
The memory block is added into [connection pool]->allocator->free[0].
There are 100MB, 101MB, and 102MB blocks.
4-4. Connection with client is closed.
So, would some of you answer to my following questions?
- Should the programmer avoid to use apr_allocator_alloc() on
connection->pool for large memory block?
- Or does the mpm worker need to destruct the connection pool, against the
current implementation?
- Or, first of all, is it appropriate that a huge memory block is pooled in
[pool]->allocator->free[0] by apr_allocator_free()? The pooled memory in
free[0] area could be leased even for very small memory request.
Thanks,
Ryujiro Shibuya