]> granicus.if.org Git - apache/commitdiff
mpm_winnt: Following up on r1801655, add a comment that explains the
authorEvgeny Kotkov <kotkov@apache.org>
Wed, 12 Jul 2017 09:47:36 +0000 (09:47 +0000)
committerEvgeny Kotkov <kotkov@apache.org>
Wed, 12 Jul 2017 09:47:36 +0000 (09:47 +0000)
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

server/mpm/winnt/child.c

index 42125af2ed5afa3484cce98a0bd87ace6e74aef3..a54c435d69619a1cb9faee69c509f5670334cfde 100644 (file)
@@ -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;