From: Evgeny Kotkov Date: Wed, 12 Jul 2017 09:47:36 +0000 (+0000) Subject: mpm_winnt: Following up on r1801655, add a comment that explains the X-Git-Tag: 2.5.0-alpha~284 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=081a04cfba74952b06fe6ed92a1a34833bc7ad58;p=apache mpm_winnt: Following up on r1801655, add a comment that explains the reason to choose the LIFO processing order for completion contexts. It would be better to keep this important information in the code, instead of just having it in the log message. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1801710 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/server/mpm/winnt/child.c b/server/mpm/winnt/child.c index 42125af2ed..a54c435d69 100644 --- a/server/mpm/winnt/child.c +++ b/server/mpm/winnt/child.c @@ -83,8 +83,33 @@ typedef VOID (WINAPI *LPFN_GETACCEPTEXSOCKADDRS)(PVOID, DWORD, DWORD, DWORD, APLOG_USE_MODULE(mpm_winnt); -/* Queue for managing the passing of winnt_conn_ctx_t between - * the accept and worker threads. +/* + * Queue for managing the passing of winnt_conn_ctx_t between the accept + * and worker threads. Note that the actual order of how the contexts + * are processed is a LIFO stack, not a FIFO queue, as LIFO order may + * significantly reduce the memory usage. + * + * Every completion context in the queue has an associated allocator, and + * every allocator has its ap_max_mem_free memory limit which is not given + * back to the OS. Once the queue grows, it cannot shrink back, and every + * allocator in each of the queued completion contexts keeps up to its + * max_free amount of memory. The queue can only grow when a server has + * to serve multiple concurrent connections at once. + * + * Consider a server that doesn't see many concurrent connections most + * of the time, but has occasional spikes when it has to deal with + * concurrency. During such spikes, the size of the queue grows. The + * difference between LIFO and FIFO shows up after such spikes, when the + * server is back to light load. + * + * With FIFO order, every completion context in the queue will be used in + * a round-robin manner, thus using *every* available allocator one by one + * and claiming up to (N * ap_max_mem_free memory) from the OS. With LIFO + * order, only the completion contexts that are close to the top of the + * stack will be used and reused for subsequent connections. Hence, only + * a small part of the allocators will be used, and this can prevent all + * other allocators from unnecessarily acquiring memory from the OS (and + * keeping it). */ typedef struct winnt_conn_ctx_t_s { struct winnt_conn_ctx_t_s *next;