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

Reply via email to