Now this may be a bit linux specific - but I'd like to get something like
this in; if needed with a #ifdef DIAG or on a per platform basis.

It is just something I've found to come in handy at various times - in
particular on Linux and with lots of heavy PHP or mod_perl.

This patch does two things

->      Collapes the near identical mutex_fcnt on/off functions
        into one.

->      Makes the wait loop no longer endless - but causes it
        to bail out (and emit some warnings ahead of time) after
        a couple of thousand consequituve EINTRs.

Does this make sense ? Objections ?

Dw

Index: http_main.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_main.c,v
retrieving revision 1.592
diff -u -r1.592 http_main.c
--- http_main.c 21 Sep 2002 17:18:34 -0000      1.592
+++ http_main.c 26 Sep 2002 00:07:20 -0000
@@ -885,37 +885,51 @@
     unlink(ap_lock_fname);
 }

-static void accept_mutex_on_fcntl(void)
+static void accept_mutex(struct flock * flag)
 {
-    int ret;
-
-    while ((ret = fcntl(lock_fd, F_SETLKW, &lock_it)) < 0 && errno == EINTR) {
-       /* nop */
+    int ret,count = 0;
+    while ((ret = fcntl(lock_fd, F_SETLKW, flag)) < 0 && errno == EINTR) {
+       count++;
+       if (count & 0x20) {
+               ap_log_error(APLOG_MARK,
+                       APLOG_INFO|APLOG_NOERRNO,server_conf,
+                               "fcntl_mutex(%slock): many EINTR's, keep trying",
+                               flag->l_type == F_UNLCK ? "un" : "");
+               if (count > 5000) {
+                       ap_log_error(APLOG_MARK,APLOG_EMERG,server_conf,
+                               "fcntl_mutex(%slock): %d EINTR's in"
+                               " a row, child exiting...",
+                               flag->l_type == F_UNLCK ? "un" : "",count);
+                       clean_child_exit(APEXIT_CHILDFATAL);
+               }
+       }
     }

     if (ret < 0) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
-                   "fcntl: F_SETLKW: Error getting accept lock, exiting!  "
-                   "Perhaps you need to use the LockFile directive to place "
-                   "your lock file on a local disk!");
+               "fcntl: F_SETLKW: Error %slocking accept lock, exiting!  "
+               "Perhaps you need to use the LockFile directive to place "
+               "your lock file on a local disk!",
+               flag->l_type == F_UNLCK ? "un" : "");
        clean_child_exit(APEXIT_CHILDFATAL);
     }
+
+    if (count > 50) {
+       ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,server_conf,
+               "fcntl_mutex(%slock): got EINTR %d consequitive times, "
+               "and finally succeeded",
+               flag->l_type == F_UNLCK ? "un" : "",count);
+   }
 }

-static void accept_mutex_off_fcntl(void)
+static void accept_mutex_on_fcntl(void)
 {
-    int ret;
+    return accept_mutex(&lock_it);
+}

-    while ((ret = fcntl(lock_fd, F_SETLKW, &unlock_it)) < 0 && errno == EINTR) {
-       /* nop */
-    }
-    if (ret < 0) {
-       ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
-                   "fcntl: F_SETLKW: Error freeing accept lock, exiting!  "
-                   "Perhaps you need to use the LockFile directive to place "
-                   "your lock file on a local disk!");
-       clean_child_exit(APEXIT_CHILDFATAL);
-    }
+static void accept_mutex_off_fcntl(void)
+{
+    return accept_mutex(&unlock_it);
 }

 accept_mutex_methods_s accept_mutex_fcntl_s = {


Reply via email to