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 = {