From 119e9482f0928f4b47d79c25b7bd1d198d68c2b8 Mon Sep 17 00:00:00 2001 From: Andre Malo Date: Sun, 22 Dec 2002 20:14:45 +0000 Subject: [PATCH] better formatting git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@98072 13f79535-47bb-0310-9956-ffa450edef68 --- docs/manual/misc/perf-tuning.html.en | 330 +++++++++++++------------ docs/manual/misc/perf-tuning.xml | 354 +++++++++++++++------------ 2 files changed, 370 insertions(+), 314 deletions(-) diff --git a/docs/manual/misc/perf-tuning.html.en b/docs/manual/misc/perf-tuning.html.en index ff6f9416c2..38421e654b 100644 --- a/docs/manual/misc/perf-tuning.html.en +++ b/docs/manual/misc/perf-tuning.html.en @@ -18,11 +18,12 @@
Apache > HTTP Server > Documentation > Version 2.1 > Miscellaneous Documentation

Apache Performance Notes

-
Warning: - This document has not been fully updated - to take into account changes made in the 2.0 version of the - Apache HTTP Server. Some of the information may still be - relevant, but please use it with care.
+

Warning:

+

This document has not been fully updated + to take into account changes made in the 2.0 version of the + Apache HTTP Server. Some of the information may still be + relevant, but please use it with care.

+

Orignally written by Dean Gaudet.

@@ -99,7 +100,7 @@ -

HostnameLookups

+

HostnameLookups

@@ -120,12 +121,14 @@ matching the criteria. Here's an example which disables lookups except for .html and .cgi files:

-
-HostnameLookups off
-<Files ~ "\.(html|cgi)$">
-    HostnameLookups on
-</Files>
-
+

+ HostnameLookups off
+ <Files ~ "\.(html|cgi)$">
+ + HostnameLookups on
+
+ </Files> +

But even still, if you just need DNS names in some CGIs you could consider doing the gethostbyname call in the @@ -142,7 +145,7 @@ HostnameLookups off -

FollowSymLinks and SymLinksIfOwnerMatch

+

FollowSymLinks and SymLinksIfOwnerMatch

@@ -152,12 +155,14 @@ HostnameLookups off system calls to check up on symlinks. One extra call per filename component. For example, if you had:

-
-DocumentRoot /www/htdocs
-<Directory />
-    Options SymLinksIfOwnerMatch
-</Directory>
-
+

+ DocumentRoot /www/htdocs
+ <Directory />
+ + Options SymLinksIfOwnerMatch
+
+ </Directory> +

and a request is made for the URI /index.html. Then Apache will perform lstat(2) on @@ -167,15 +172,20 @@ DocumentRoot /www/htdocs every single request. If you really desire the symlinks security checking you can do something like this:

-
-DocumentRoot /www/htdocs
-<Directory />
-    Options FollowSymLinks
-</Directory>
-<Directory /www/htdocs>
-    Options -FollowSymLinks +SymLinksIfOwnerMatch
-</Directory>
-
+

+ DocumentRoot /www/htdocs
+ <Directory />
+ + Options FollowSymLinks
+
+ </Directory>
+
+ <Directory /www/htdocs>
+ + Options -FollowSymLinks +SymLinksIfOwnerMatch
+
+ </Directory> +

This at least avoids the extra checks for the DocumentRoot path. @@ -188,7 +198,7 @@ DocumentRoot /www/htdocs -

AllowOverride

+

AllowOverride

@@ -197,12 +207,14 @@ DocumentRoot /www/htdocs .htaccess for each filename component. For example,

-
-DocumentRoot /www/htdocs
-<Directory />
-    AllowOverride all
-</Directory>
-
+

+ DocumentRoot /www/htdocs
+ <Directory />
+ + AllowOverride all
+
+ </Directory> +

and a request is made for the URI /index.html. Then Apache will attempt to open /.htaccess, @@ -224,15 +236,15 @@ DocumentRoot /www/htdocs penalties. There's one case where you can speed up the server. Instead of using a wildcard such as:

-
-DirectoryIndex index
-
+

+ DirectoryIndex index +

-

Use a complete list of options:

+

Use a complete list of options:

-
-DirectoryIndex index.cgi index.pl index.shtml index.html
-
+

+ DirectoryIndex index.cgi index.pl index.shtml index.html +

where you list the most common choice first.

@@ -406,29 +418,39 @@ DirectoryIndex index.cgi index.pl index.shtml index.html do not match the code, they're contrived for pedagogical purposes):

-
-    for (;;) {
-    for (;;) {
-        fd_set accept_fds;
-
-        FD_ZERO (&accept_fds);
-        for (i = first_socket; i <= last_socket; ++i) {
-        FD_SET (i, &accept_fds);
-        }
-        rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
-        if (rc < 1) continue;
-        new_connection = -1;
-        for (i = first_socket; i <= last_socket; ++i) {
-        if (FD_ISSET (i, &accept_fds)) {
-            new_connection = accept (i, NULL, NULL);
-            if (new_connection != -1) break;
-        }
+      

+ for (;;) {
+ + for (;;) {
+ + fd_set accept_fds;
+
+ FD_ZERO (&accept_fds);
+ for (i = first_socket; i <= last_socket; ++i) {
+ + FD_SET (i, &accept_fds);
+
+ }
+ rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
+ if (rc < 1) continue;
+ new_connection = -1;
+ for (i = first_socket; i <= last_socket; ++i) {
+ + if (FD_ISSET (i, &accept_fds)) {
+ + new_connection = accept (i, NULL, NULL);
+ if (new_connection != -1) break;
+
+ }
+
+ }
+ if (new_connection != -1) break;
+
+ }
+ process the new_connection;
+
} - if (new_connection != -1) break; - } - process the new_connection; - } -

+

But this naive implementation has a serious starvation problem. Recall that multiple children execute this loop at the same @@ -466,31 +488,41 @@ DirectoryIndex index.cgi index.pl index.shtml index.html entry into the inner loop. The loop looks like this (differences highlighted):

-
-    for (;;) {
-    accept_mutex_on ();
-    for (;;) {
-        fd_set accept_fds;
-
-        FD_ZERO (&accept_fds);
-        for (i = first_socket; i <= last_socket; ++i) {
-        FD_SET (i, &accept_fds);
-        }
-        rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
-        if (rc < 1) continue;
-        new_connection = -1;
-        for (i = first_socket; i <= last_socket; ++i) {
-        if (FD_ISSET (i, &accept_fds)) {
-            new_connection = accept (i, NULL, NULL);
-            if (new_connection != -1) break;
-        }
+      

+ for (;;) {
+ + accept_mutex_on ();
+ for (;;) {
+ + fd_set accept_fds;
+
+ FD_ZERO (&accept_fds);
+ for (i = first_socket; i <= last_socket; ++i) {
+ + FD_SET (i, &accept_fds);
+
+ }
+ rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
+ if (rc < 1) continue;
+ new_connection = -1;
+ for (i = first_socket; i <= last_socket; ++i) {
+ + if (FD_ISSET (i, &accept_fds)) {
+ + new_connection = accept (i, NULL, NULL);
+ if (new_connection != -1) break;
+
+ }
+
+ }
+ if (new_connection != -1) break;
+
+ }
+ accept_mutex_off ();
+ process the new_connection;
+
} - if (new_connection != -1) break; - } - accept_mutex_off (); - process the new_connection; - } -

+

The functions accept_mutex_on and accept_mutex_off @@ -660,31 +692,39 @@ DirectoryIndex index.cgi index.pl index.shtml index.html http_main.c). The function looks roughly like this:

-
-    void lingering_close (int s)
-    {
-    char junk_buffer[2048];
-
-    /* shutdown the sending side */
-    shutdown (s, 1);
-
-    signal (SIGALRM, lingering_death);
-    alarm (30);
-
-    for (;;) {
-        select (s for reading, 2 second timeout);
-        if (error) break;
-        if (s is ready for reading) {
-        if (read (s, junk_buffer, sizeof (junk_buffer)) <= 0) {
-            break;
+      

+ void lingering_close (int s)
+ {
+ + char junk_buffer[2048];
+
+ /* shutdown the sending side */
+ shutdown (s, 1);
+
+ signal (SIGALRM, lingering_death);
+ alarm (30);
+
+ for (;;) {
+ + select (s for reading, 2 second timeout);
+ if (error) break;
+ if (s is ready for reading) {
+ + if (read (s, junk_buffer, sizeof (junk_buffer)) <= 0) {
+ + break;
+
+ }
+ /* just toss away whatever is here */
+
+ }
+
+ }
+
+ close (s);
+
} - /* just toss away whatever is here */ - } - } - - close (s); - } -

+

This naturally adds some expense at the end of a connection, but it is required for a reliable implementation. As HTTP/1.1 @@ -728,7 +768,7 @@ DirectoryIndex index.cgi index.pl index.shtml index.html -

DYNAMIC_MODULE_LIMIT

+

DYNAMIC_MODULE_LIMIT

@@ -751,7 +791,7 @@ DirectoryIndex index.cgi index.pl index.shtml index.html on Solaris 8. This trace was collected using:

- truss -l -p httpd_child_pid. + truss -l -p httpd_child_pid.

The -l option tells truss to log the ID of the @@ -767,10 +807,8 @@ DirectoryIndex index.cgi index.pl index.shtml index.html with content negotiation look wildly different (and quite ugly in some cases).

-
-/67:    accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...)
-/67:    accept(3, 0x00200BEC, 0x00200C0C, 1)            = 9
-
+
/67:    accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...)
+/67:    accept(3, 0x00200BEC, 0x00200C0C, 1)            = 9

In this trace, the listener thread is running within LWP #67.

@@ -778,18 +816,14 @@ DirectoryIndex index.cgi index.pl index.shtml index.html particular platform, the worker MPM uses an unserialized accept by default unless it is listening on multiple ports. -
-/65:    lwp_park(0x00000000, 0)                         = 0
-/67:    lwp_unpark(65, 1)                               = 0
-
+
/65:    lwp_park(0x00000000, 0)                         = 0
+/67:    lwp_unpark(65, 1)                               = 0

Upon accepting the connection, the listener thread wakes up a worker thread to do the request processing. In this trace, the worker thread that handles the request is mapped to LWP #65.

-
-/65:    getsockname(9, 0x00200BA4, 0x00200BC4, 1)       = 0
-
+
/65:    getsockname(9, 0x00200BA4, 0x00200BC4, 1)       = 0

In order to implement virtual hosts, Apache needs to know the local socket address used to accept the connection. It @@ -799,10 +833,8 @@ DirectoryIndex index.cgi index.pl index.shtml index.html are used which do not have wildcard addresses). But no effort has yet been made to do these optimizations.

-
-/65:    brk(0x002170E8)                                 = 0
-/65:    brk(0x002190E8)                                 = 0
-
+
/65:    brk(0x002170E8)                                 = 0
+/65:    brk(0x002190E8)                                 = 0

The brk(2) calls allocate memory from the heap. It is rare to see these in a system call trace, because the httpd @@ -812,31 +844,25 @@ DirectoryIndex index.cgi index.pl index.shtml index.html call malloc(3) to get the blocks of raw memory with which to create the custom memory allocators.

-
-/65:    fcntl(9, F_GETFL, 0x00000000)                   = 2
+    
/65:    fcntl(9, F_GETFL, 0x00000000)                   = 2
 /65:    fstat64(9, 0xFAF7B818)                          = 0
 /65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B910, 2190656) = 0
 /65:    fstat64(9, 0xFAF7B818)                          = 0
 /65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B914, 2190656) = 0
 /65:    setsockopt(9, 65535, 8192, 0xFAF7B918, 4, 2190656) = 0
-/65:    fcntl(9, F_SETFL, 0x00000082)                   = 0
-
+/65: fcntl(9, F_SETFL, 0x00000082) = 0

Next, the worker thread puts the connection to the client (file descriptor 9) in non-blocking mode. The setsockopt(2) and getsockopt(2) calls are a side-effect of how Solaris's libc handles fcntl(2) on sockets.

-
-/65:    read(9, " G E T   / 1 0 k . h t m".., 8000)     = 97
-
+
/65:    read(9, " G E T   / 1 0 k . h t m".., 8000)     = 97

The worker thread reads the request from the client.

-
-/65:    stat("/var/httpd/apache/httpd-8999/htdocs/10k.html", 0xFAF7B978) = 0
-/65:    open("/var/httpd/apache/httpd-8999/htdocs/10k.html", O_RDONLY) = 10
-
+
/65:    stat("/var/httpd/apache/httpd-8999/htdocs/10k.html", 0xFAF7B978) = 0
+/65:    open("/var/httpd/apache/httpd-8999/htdocs/10k.html", O_RDONLY) = 10

This httpd has been configured with Options FollowSymLinks and AllowOverride None. Thus it doesn't need to @@ -845,9 +871,7 @@ DirectoryIndex index.cgi index.pl index.shtml index.html It simply calls stat(2) to verify that the file: 1) exists, and 2) is a regular file, not a directory.

-
-/65:    sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C)      = 10269
-
+
/65:    sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C)      = 10269

In this example, the httpd is able to send the HTTP response header and the requested file with a single sendfilev(2) @@ -856,9 +880,7 @@ DirectoryIndex index.cgi index.pl index.shtml index.html writev(2) call to send the headers before calling sendfile(2).

-
-/65:    write(4, " 1 2 7 . 0 . 0 . 1   -  ".., 78)      = 78
-
+
/65:    write(4, " 1 2 7 . 0 . 0 . 1   -  ".., 78)      = 78

This write(2) call records the request in the access log. Note that one thing missing from this trace is a @@ -868,26 +890,20 @@ DirectoryIndex index.cgi index.pl index.shtml index.html optimized implementation that doesn't require as much overhead as a typical system call.

-
-/65:    shutdown(9, 1, 1)                               = 0
+    
/65:    shutdown(9, 1, 1)                               = 0
 /65:    poll(0xFAF7B980, 1, 2000)                       = 1
 /65:    read(9, 0xFAF7BC20, 512)                        = 0
-/65:    close(9)                                        = 0
-
+/65: close(9) = 0

The worker thread does a lingering close of the connection.

-
-/65:    close(10)                                       = 0
-/65:    lwp_park(0x00000000, 0)         (sleeping...)
-
+
/65:    close(10)                                       = 0
+/65:    lwp_park(0x00000000, 0)         (sleeping...)

Finally the worker thread closes the file that it has just delivered and blocks until the listener assigns it another connection.

-
-/67:    accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)
-
+
/67:    accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)

Meanwhile, the listener thread is able to accept another connection as soon as it has dispatched this connection to a worker thread (subject diff --git a/docs/manual/misc/perf-tuning.xml b/docs/manual/misc/perf-tuning.xml index f792624ec1..5c7db1f20f 100644 --- a/docs/manual/misc/perf-tuning.xml +++ b/docs/manual/misc/perf-tuning.xml @@ -10,11 +10,12 @@

- Warning: - This document has not been fully updated - to take into account changes made in the 2.0 version of the - Apache HTTP Server. Some of the information may still be - relevant, but please use it with care. + Warning: +

This document has not been fully updated + to take into account changes made in the 2.0 version of the + Apache HTTP Server. Some of the information may still be + relevant, but please use it with care.

+

Orignally written by Dean Gaudet.

@@ -106,7 +107,7 @@
- <code>HostnameLookups</code> + HostnameLookups

Prior to Apache 1.3, HostnameLookups defaulted to On. @@ -126,12 +127,14 @@ matching the criteria. Here's an example which disables lookups except for .html and .cgi files:

-
-HostnameLookups off
-<Files ~ "\.(html|cgi)$">
-    HostnameLookups on
-</Files>
-
+ + HostnameLookups off
+ <Files ~ "\.(html|cgi)$">
+ + HostnameLookups on
+
+ </Files> +

But even still, if you just need DNS names in some CGIs you could consider doing the gethostbyname call in the @@ -151,7 +154,7 @@ HostnameLookups off

- <code>FollowSymLinks</code> and <code>SymLinksIfOwnerMatch</code> + FollowSymLinks and SymLinksIfOwnerMatch

Wherever in your URL-space you do not have an Options FollowSymLinks, or you do have an Options @@ -159,12 +162,14 @@ HostnameLookups off system calls to check up on symlinks. One extra call per filename component. For example, if you had:

-
-DocumentRoot /www/htdocs
-<Directory />
-    Options SymLinksIfOwnerMatch
-</Directory>
-
+ + DocumentRoot /www/htdocs
+ <Directory />
+ + Options SymLinksIfOwnerMatch
+
+ </Directory> +

and a request is made for the URI /index.html. Then Apache will perform lstat(2) on @@ -174,15 +179,20 @@ DocumentRoot /www/htdocs every single request. If you really desire the symlinks security checking you can do something like this:

-
-DocumentRoot /www/htdocs
-<Directory />
-    Options FollowSymLinks
-</Directory>
-<Directory /www/htdocs>
-    Options -FollowSymLinks +SymLinksIfOwnerMatch
-</Directory>
-
+ + DocumentRoot /www/htdocs
+ <Directory />
+ + Options FollowSymLinks
+
+ </Directory>
+
+ <Directory /www/htdocs>
+ + Options -FollowSymLinks +SymLinksIfOwnerMatch
+
+ </Directory> +

This at least avoids the extra checks for the DocumentRoot path. @@ -197,19 +207,21 @@ DocumentRoot /www/htdocs

- <code>AllowOverride</code> + AllowOverride

Wherever in your URL-space you allow overrides (typically .htaccess files) Apache will attempt to open .htaccess for each filename component. For example,

-
-DocumentRoot /www/htdocs
-<Directory />
-    AllowOverride all
-</Directory>
-
+ + DocumentRoot /www/htdocs
+ <Directory />
+ + AllowOverride all
+
+ </Directory> +

and a request is made for the URI /index.html. Then Apache will attempt to open /.htaccess, @@ -231,15 +243,15 @@ DocumentRoot /www/htdocs penalties. There's one case where you can speed up the server. Instead of using a wildcard such as:

-
-DirectoryIndex index
-
+ + DirectoryIndex index + -

Use a complete list of options:

+

Use a complete list of options:

-
-DirectoryIndex index.cgi index.pl index.shtml index.html
-
+ + DirectoryIndex index.cgi index.pl index.shtml index.html +

where you list the most common choice first.

@@ -423,29 +435,39 @@ DirectoryIndex index.cgi index.pl index.shtml index.html do not match the code, they're contrived for pedagogical purposes):

-
-    for (;;) {
-    for (;;) {
-        fd_set accept_fds;
-
-        FD_ZERO (&accept_fds);
-        for (i = first_socket; i <= last_socket; ++i) {
-        FD_SET (i, &accept_fds);
-        }
-        rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
-        if (rc < 1) continue;
-        new_connection = -1;
-        for (i = first_socket; i <= last_socket; ++i) {
-        if (FD_ISSET (i, &accept_fds)) {
-            new_connection = accept (i, NULL, NULL);
-            if (new_connection != -1) break;
-        }
+      
+        for (;;) {
+ + for (;;) {
+ + fd_set accept_fds;
+
+ FD_ZERO (&accept_fds);
+ for (i = first_socket; i <= last_socket; ++i) {
+ + FD_SET (i, &accept_fds);
+
+ }
+ rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
+ if (rc < 1) continue;
+ new_connection = -1;
+ for (i = first_socket; i <= last_socket; ++i) {
+ + if (FD_ISSET (i, &accept_fds)) {
+ + new_connection = accept (i, NULL, NULL);
+ if (new_connection != -1) break;
+
+ }
+
+ }
+ if (new_connection != -1) break;
+
+ }
+ process the new_connection;
+
} - if (new_connection != -1) break; - } - process the new_connection; - } -
+

But this naive implementation has a serious starvation problem. Recall that multiple children execute this loop at the same @@ -484,31 +506,41 @@ DirectoryIndex index.cgi index.pl index.shtml index.html entry into the inner loop. The loop looks like this (differences highlighted):

-
-    for (;;) {
-    accept_mutex_on ();
-    for (;;) {
-        fd_set accept_fds;
-
-        FD_ZERO (&accept_fds);
-        for (i = first_socket; i <= last_socket; ++i) {
-        FD_SET (i, &accept_fds);
-        }
-        rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
-        if (rc < 1) continue;
-        new_connection = -1;
-        for (i = first_socket; i <= last_socket; ++i) {
-        if (FD_ISSET (i, &accept_fds)) {
-            new_connection = accept (i, NULL, NULL);
-            if (new_connection != -1) break;
+      
+        for (;;) {
+ + accept_mutex_on ();
+ for (;;) {
+ + fd_set accept_fds;
+
+ FD_ZERO (&accept_fds);
+ for (i = first_socket; i <= last_socket; ++i) {
+ + FD_SET (i, &accept_fds);
+
+ }
+ rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
+ if (rc < 1) continue;
+ new_connection = -1;
+ for (i = first_socket; i <= last_socket; ++i) {
+ + if (FD_ISSET (i, &accept_fds)) {
+ + new_connection = accept (i, NULL, NULL);
+ if (new_connection != -1) break;
+
+ }
+
+ }
+ if (new_connection != -1) break;
+
+ }
+ accept_mutex_off ();
+ process the new_connection;
+
} - } - if (new_connection != -1) break; - } - accept_mutex_off (); - process the new_connection; - } -
+

The functions accept_mutex_on and accept_mutex_off @@ -681,31 +713,39 @@ DirectoryIndex index.cgi index.pl index.shtml index.html http_main.c). The function looks roughly like this:

-
-    void lingering_close (int s)
-    {
-    char junk_buffer[2048];
-
-    /* shutdown the sending side */
-    shutdown (s, 1);
-
-    signal (SIGALRM, lingering_death);
-    alarm (30);
-
-    for (;;) {
-        select (s for reading, 2 second timeout);
-        if (error) break;
-        if (s is ready for reading) {
-        if (read (s, junk_buffer, sizeof (junk_buffer)) <= 0) {
-            break;
+      
+        void lingering_close (int s)
+ {
+ + char junk_buffer[2048];
+
+ /* shutdown the sending side */
+ shutdown (s, 1);
+
+ signal (SIGALRM, lingering_death);
+ alarm (30);
+
+ for (;;) {
+ + select (s for reading, 2 second timeout);
+ if (error) break;
+ if (s is ready for reading) {
+ + if (read (s, junk_buffer, sizeof (junk_buffer)) <= 0) {
+ + break;
+
+ }
+ /* just toss away whatever is here */
+
+ }
+
+ }
+
+ close (s);
+
} - /* just toss away whatever is here */ - } - } - - close (s); - } -
+

This naturally adds some expense at the end of a connection, but it is required for a reliable implementation. As HTTP/1.1 @@ -752,7 +792,7 @@ DirectoryIndex index.cgi index.pl index.shtml index.html

- <code>DYNAMIC_MODULE_LIMIT</code> + DYNAMIC_MODULE_LIMIT

If you have no intention of using dynamically loaded modules (you probably don't if you're reading this and tuning your @@ -773,7 +813,7 @@ DirectoryIndex index.cgi index.pl index.shtml index.html on Solaris 8. This trace was collected using:

- truss -l -p httpd_child_pid. + truss -l -p httpd_child_pid.

The -l option tells truss to log the ID of the @@ -789,10 +829,10 @@ DirectoryIndex index.cgi index.pl index.shtml index.html with content negotiation look wildly different (and quite ugly in some cases).

-
-/67:    accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...)
-/67:    accept(3, 0x00200BEC, 0x00200C0C, 1)            = 9
-
+ +
/67:    accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...)
+/67:    accept(3, 0x00200BEC, 0x00200C0C, 1)            = 9
+

In this trace, the listener thread is running within LWP #67.

@@ -800,18 +840,18 @@ DirectoryIndex index.cgi index.pl index.shtml index.html particular platform, the worker MPM uses an unserialized accept by default unless it is listening on multiple ports. -
-/65:    lwp_park(0x00000000, 0)                         = 0
-/67:    lwp_unpark(65, 1)                               = 0
-
+ +
/65:    lwp_park(0x00000000, 0)                         = 0
+/67:    lwp_unpark(65, 1)                               = 0
+

Upon accepting the connection, the listener thread wakes up a worker thread to do the request processing. In this trace, the worker thread that handles the request is mapped to LWP #65.

-
-/65:    getsockname(9, 0x00200BA4, 0x00200BC4, 1)       = 0
-
+ +
/65:    getsockname(9, 0x00200BA4, 0x00200BC4, 1)       = 0
+

In order to implement virtual hosts, Apache needs to know the local socket address used to accept the connection. It @@ -821,10 +861,10 @@ DirectoryIndex index.cgi index.pl index.shtml index.html are used which do not have wildcard addresses). But no effort has yet been made to do these optimizations.

-
-/65:    brk(0x002170E8)                                 = 0
-/65:    brk(0x002190E8)                                 = 0
-
+ +
/65:    brk(0x002170E8)                                 = 0
+/65:    brk(0x002190E8)                                 = 0
+

The brk(2) calls allocate memory from the heap. It is rare to see these in a system call trace, because the httpd @@ -834,31 +874,31 @@ DirectoryIndex index.cgi index.pl index.shtml index.html call malloc(3) to get the blocks of raw memory with which to create the custom memory allocators.

-
-/65:    fcntl(9, F_GETFL, 0x00000000)                   = 2
+    
+
/65:    fcntl(9, F_GETFL, 0x00000000)                   = 2
 /65:    fstat64(9, 0xFAF7B818)                          = 0
 /65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B910, 2190656) = 0
 /65:    fstat64(9, 0xFAF7B818)                          = 0
 /65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B914, 2190656) = 0
 /65:    setsockopt(9, 65535, 8192, 0xFAF7B918, 4, 2190656) = 0
-/65:    fcntl(9, F_SETFL, 0x00000082)                   = 0
-
+/65: fcntl(9, F_SETFL, 0x00000082) = 0
+

Next, the worker thread puts the connection to the client (file descriptor 9) in non-blocking mode. The setsockopt(2) and getsockopt(2) calls are a side-effect of how Solaris's libc handles fcntl(2) on sockets.

-
-/65:    read(9, " G E T   / 1 0 k . h t m".., 8000)     = 97
-
+ +
/65:    read(9, " G E T   / 1 0 k . h t m".., 8000)     = 97
+

The worker thread reads the request from the client.

-
-/65:    stat("/var/httpd/apache/httpd-8999/htdocs/10k.html", 0xFAF7B978) = 0
-/65:    open("/var/httpd/apache/httpd-8999/htdocs/10k.html", O_RDONLY) = 10
-
+ +
/65:    stat("/var/httpd/apache/httpd-8999/htdocs/10k.html", 0xFAF7B978) = 0
+/65:    open("/var/httpd/apache/httpd-8999/htdocs/10k.html", O_RDONLY) = 10
+

This httpd has been configured with Options FollowSymLinks and AllowOverride None. Thus it doesn't need to @@ -867,9 +907,9 @@ DirectoryIndex index.cgi index.pl index.shtml index.html It simply calls stat(2) to verify that the file: 1) exists, and 2) is a regular file, not a directory.

-
-/65:    sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C)      = 10269
-
+ +
/65:    sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C)      = 10269
+

In this example, the httpd is able to send the HTTP response header and the requested file with a single sendfilev(2) @@ -878,9 +918,9 @@ DirectoryIndex index.cgi index.pl index.shtml index.html writev(2) call to send the headers before calling sendfile(2).

-
-/65:    write(4, " 1 2 7 . 0 . 0 . 1   -  ".., 78)      = 78
-
+ +
/65:    write(4, " 1 2 7 . 0 . 0 . 1   -  ".., 78)      = 78
+

This write(2) call records the request in the access log. Note that one thing missing from this trace is a @@ -890,26 +930,26 @@ DirectoryIndex index.cgi index.pl index.shtml index.html optimized implementation that doesn't require as much overhead as a typical system call.

-
-/65:    shutdown(9, 1, 1)                               = 0
+    
+
/65:    shutdown(9, 1, 1)                               = 0
 /65:    poll(0xFAF7B980, 1, 2000)                       = 1
 /65:    read(9, 0xFAF7BC20, 512)                        = 0
-/65:    close(9)                                        = 0
-
+/65: close(9) = 0
+

The worker thread does a lingering close of the connection.

-
-/65:    close(10)                                       = 0
-/65:    lwp_park(0x00000000, 0)         (sleeping...)
-
+ +
/65:    close(10)                                       = 0
+/65:    lwp_park(0x00000000, 0)         (sleeping...)
+

Finally the worker thread closes the file that it has just delivered and blocks until the listener assigns it another connection.

-
-/67:    accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)
-
+ +
/67:    accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)
+

Meanwhile, the listener thread is able to accept another connection as soon as it has dispatched this connection to a worker thread (subject -- 2.40.0