]> granicus.if.org Git - php/commitdiff
- Fixed bug #52501 (libevent made FPM crashed when forking -- libevent has been removed)
authorJérôme Loyet <fat@php.net>
Fri, 26 Nov 2010 13:46:15 +0000 (13:46 +0000)
committerJérôme Loyet <fat@php.net>
Fri, 26 Nov 2010 13:46:15 +0000 (13:46 +0000)
14 files changed:
NEWS
sapi/fpm/config.m4
sapi/fpm/fpm/fpm.c
sapi/fpm/fpm/fpm.h
sapi/fpm/fpm/fpm_children.c
sapi/fpm/fpm/fpm_children.h
sapi/fpm/fpm/fpm_events.c
sapi/fpm/fpm/fpm_events.h
sapi/fpm/fpm/fpm_main.c
sapi/fpm/fpm/fpm_process_ctl.c
sapi/fpm/fpm/fpm_process_ctl.h
sapi/fpm/fpm/fpm_stdio.c
sapi/fpm/fpm/fpm_stdio.h
sapi/fpm/php-fpm.conf.in

diff --git a/NEWS b/NEWS
index da02f609c8528a278afbbf79ede801bdab126386..9ea0f828f83e6b69fd2d9c743277dc2e2c4da0f6 100644 (file)
--- a/NEWS
+++ b/NEWS
    
 - PHP-FPM SAPI:
   . Fixed inconsistent backlog default value (-1) in FPM on many systems. (fat)
+  . Fixed bug #52501 (libevent made FPM crashed when forking -- libevent has
+    been removed). (fat)
   . Fixed bug #52725 (gcc builtin atomic functions were sometimes used when they
     were not available). (fat)
   . Fixed bug #52693 (configuration file errors are not logged to stderr). (fat)
index 85100dfa4bac3dbaedeb5dd0c9a47dcc8e8ca23d..6899ea790b921cc7833cca93ed0e85dd3ec9f65f 100644 (file)
@@ -2,220 +2,9 @@ dnl
 dnl $Id$
 dnl
 
-minimum_libevent_version="1.4.11"
-
 PHP_ARG_ENABLE(fpm,,
 [  --enable-fpm              EXPERIMENTAL: Enable building of the fpm SAPI executable], no, no)
 
-dnl libevent check function {{{
-dnl @synopsis AC_LIB_EVENT([MINIMUM-VERSION])
-dnl
-dnl Test for the libevent library of a particular version (or newer).
-dnl Source: http://svn.apache.org/repos/asf/incubator/thrift/trunk/aclocal/ax_lib_event.m4
-dnl Modified: This file was modified for autoconf-2.13 and the PHP_ARG_WITH macro.
-dnl
-dnl If no path to the installed libevent is given, the macro will first try
-dnl using no -I or -L flags, then searches under /usr, /usr/local, /opt,
-dnl and /opt/libevent.
-dnl If these all fail, it will try the $LIBEVENT_ROOT environment variable.
-dnl
-dnl This macro requires that #include <sys/types.h> works and defines u_char.
-dnl
-dnl This macro calls:
-dnl   AC_SUBST(LIBEVENT_CFLAGS)
-dnl   AC_SUBST(LIBEVENT_LIBS)
-dnl
-dnl And (if libevent is found):
-dnl   AC_DEFINE(HAVE_LIBEVENT)
-dnl
-dnl It also leaves the shell variables "success" and "ac_have_libevent"
-dnl set to "yes" or "no".
-dnl
-dnl NOTE: This macro does not currently work for cross-compiling,
-dnl       but it can be easily modified to allow it.  (grep "cross").
-dnl
-dnl @category InstalledPackages
-dnl @category C
-dnl @version 2007-09-12
-dnl @license AllPermissive
-dnl
-dnl Copyright (C) 2009 David Reiss
-dnl Copying and distribution of this file, with or without modification,
-dnl are permitted in any medium without royalty provided the copyright
-dnl notice and this notice are preserved.
-
-AC_DEFUN([AC_LIB_EVENT_DO_CHECK],
-[
-# Save our flags.
-CPPFLAGS_SAVED="$CPPFLAGS"
-LDFLAGS_SAVED="$LDFLAGS"
-LIBS_SAVED="$LIBS"
-LD_LIBRARY_PATH_SAVED="$LD_LIBRARY_PATH"
-
-# Set our flags if we are checking a specific directory.
-if test -n "$ac_libevent_path" ; then
-  LIBEVENT_CPPFLAGS="-I$ac_libevent_path/include"
-  if test -z "$PHP_LIBDIR"; then
-    LIBEVENT_LDFLAGS="-L$ac_libevent_path/lib"
-  else 
-    LIBEVENT_LDFLAGS="-L$ac_libevent_path/$PHP_LIBDIR"
-  fi
-
-  LD_LIBRARY_PATH="$ac_libevent_path/lib:$LD_LIBRARY_PATH"
-else
-  LIBEVENT_CPPFLAGS=""
-  LIBEVENT_LDFLAGS=""
-fi
-
-# Required flag for libevent.
-LIBEVENT_LIBS="-levent"
-
-# Prepare the environment for compilation.
-CPPFLAGS="$CPPFLAGS $LIBEVENT_CPPFLAGS"
-LDFLAGS="$LDFLAGS $LIBEVENT_LDFLAGS"
-LIBS="$LIBS $LIBEVENT_LIBS"
-export CPPFLAGS
-export LDFLAGS
-export LIBS
-export LD_LIBRARY_PATH
-
-success=no
-
-# Compile, link, and run the program.  This checks:
-# - event.h is available for including.
-# - event_get_version() is available for linking.
-# - The event version string is lexicographically greater
-#   than the required version.
-AC_TRY_RUN([
-#include <sys/types.h>
-#include <event.h>
-
-int main(int argc, char *argv[])
-{
-       const char* lib_version = event_get_version();
-       const char* wnt_version = "$WANT_LIBEVENT_VERSION";
-       for (;;) {
-               /* If we reached the end of the want version.  We have it. */
-               if (*wnt_version == '\0' || *wnt_version == '-') {
-                       return 0;
-               }
-               /* If the want version continues but the lib version does not, */
-               /* we are missing a letter.  We don't have it. */
-               if (*lib_version == '\0' || *lib_version == '-') {
-                       return 1;
-               }
-
-               /* In the 1.4 version numbering style, if there are more digits */
-               /* in one version than the other, that one is higher. */
-               int lib_digits;
-               for (lib_digits = 0;
-               lib_version[lib_digits] >= '0' &&
-               lib_version[lib_digits] <= '9';
-               lib_digits++)
-               ;
-               int wnt_digits;
-               for (wnt_digits = 0;
-               wnt_version[wnt_digits] >= '0' &&
-               wnt_version[wnt_digits] <= '9';
-               wnt_digits++)
-               ;
-               if (lib_digits > wnt_digits) {
-                       return 0;
-               }
-               if (lib_digits < wnt_digits) {
-                       return 1;
-               }
-               /* If we have greater than what we want.  We have it. */
-               if (*lib_version > *wnt_version) {
-                       return 0;
-               }
-               /* If we have less, we don't. */
-               if (*lib_version < *wnt_version) {
-                       return 1;
-               }
-               lib_version++;
-               wnt_version++;
-       }
-       return 0;
-}
-],[
-success=yes
-])
-
-# Restore flags.
-CPPFLAGS="$CPPFLAGS_SAVED"
-LDFLAGS="$LDFLAGS_SAVED"
-LIBS="$LIBS_SAVED"
-LD_LIBRARY_PATH="$LD_LIBRARY_PATH_SAVED"
-])
-
-AC_DEFUN([AC_LIB_EVENT],
-[
-
-PHP_ARG_WITH(libevent-dir,,
-[  --with-libevent-dir[=PATH]  libevent install prefix, for fpm SAPI. (default: /usr/local)], /usr/local, yes)
-
-if test "$PHP_LIBEVENT_DIR" != "no"; then
-  WANT_LIBEVENT_VERSION=ifelse([$1], ,1.2,$1)
-
-  AC_MSG_CHECKING(for libevent >= $WANT_LIBEVENT_VERSION install prefix)
-
-  libevent_prefix=$ac_default_prefix
-  if test $prefix != "NONE" -a $prefix != "" -a $prefix != "no" ; then 
-    libevent_prefix=$prefix
-  fi
-
-  if test "$PHP_LIBEVENT_DIR" = "yes"; then
-    PHP_LIBEVENT_DIR=$libevent_prefix
-  fi
-
-  if test "$PHP_LIBEVENT_DIR" != "yes" && test "$PHP_LIBEVENT_DIR" != "/usr/local"; then
-    dnl don't try to be too smart, check only $PHP_LIBEVENT_DIR if specified
-    ac_libevent_path=$PHP_LIBEVENT_DIR
-    AC_LIB_EVENT_DO_CHECK
-    if test "$success" = "no"; then
-      AC_MSG_ERROR([Could not find libevent >= $WANT_LIBEVENT_VERSION in $PHP_LIBEVENT_DIR])
-    fi
-   else 
-    dnl check default prefixes then
-    for ac_libevent_path in "" $PHP_LIBEVENT_DIR /usr /usr/local /opt /opt/local /opt/libevent ; do
-      AC_LIB_EVENT_DO_CHECK
-      if test "$success" = "yes"; then
-        break;
-      fi
-    done
-  fi
-
-  if test "$success" != "yes" ; then
-    AC_MSG_RESULT(no)
-    ac_have_libevent=no
-    AC_MSG_ERROR([libevent >= $WANT_LIBEVENT_VERSION could not be found])
-  else
-    AC_MSG_RESULT($ac_libevent_path)
-    ac_have_libevent=yes
-    AC_DEFINE(HAVE_LIBEVENT, 1, [define if libevent is available])
-  fi
-
-  LIBEVENT_LIBS="-levent"
-
-  if test -n "$ac_libevent_path"; then
-    LIBEVENT_CFLAGS="-I$ac_libevent_path/include"
-    LIBEVENT_LIBS="-L$ac_libevent_path/$PHP_LIBDIR $LIBEVENT_LIBS"
-    LIBEVENT_PATH="$ac_libevent_path/$PHP_LIBDIR"
-  fi
-
-  AC_SUBST(LIBEVENT_CFLAGS)
-  AC_SUBST(LIBEVENT_LIBS)
-  AC_SUBST(LIBEVENT_PATH)
-
-else
-  AC_MSG_ERROR([FPM requires libevent >= $WANT_LIBEVENT_VERSION. Please specify libevent install prefix with --with-libevent-dir=yes])
-fi
-
-])
-dnl }}}
-
 dnl configure checks {{{
 AC_DEFUN([AC_FPM_STDLIBS],
 [
@@ -555,22 +344,6 @@ AC_MSG_CHECKING(for FPM build)
 if test "$PHP_FPM" != "no"; then
   AC_MSG_RESULT($PHP_FPM)
 
-  AC_LIB_EVENT([$minimum_libevent_version])
-
-  dnl check libevent build
-  LD_LIBRARY_PATH_SAVED="$LD_LIBRARY_PATH"
-  export LD_LIBRARY_PATH="$LIBEVENT_PATH:$LD_LIBRARY_PATH"
-
-  AC_MSG_CHECKING(whether libevent build works)
-    PHP_TEST_BUILD(event_init, [
-    AC_MSG_RESULT(yes)
-  ], [
-    AC_MSG_RESULT(no)
-    AC_MSG_ERROR([build test failed. Please check the config.log for details])
-  ], $LIBEVENT_LIBS)
-
-  export LD_LIBRARY_PATH="$LD_LIBRARY_PATH_SAVED"
-
   AC_FPM_STDLIBS
   AC_FPM_PRCTL
   AC_FPM_CLOCK
@@ -619,10 +392,7 @@ if test "$PHP_FPM" != "no"; then
     PHP_FPM_TRACE_FILES="fpm/fpm_trace.c fpm/fpm_trace_$fpm_trace_type.c"
   fi
   
-  PHP_FPM_CFLAGS="$LIBEVENT_CFLAGS -I$abs_srcdir/sapi/fpm"
-
-  SAPI_EXTRA_LIBS="$LIBEVENT_LIBS"
-  PHP_SUBST(SAPI_EXTRA_LIBS)
+  PHP_FPM_CFLAGS="-I$abs_srcdir/sapi/fpm"
  
   INSTALL_IT=":"
   PHP_FPM_FILES="fpm/fastcgi.c \
index 987e13c3ffcf042d190c360872de08f85f2fbfeb..60e8e4ef3a73a8e7c25fb37af304aa812a6df9bd 100644 (file)
@@ -23,7 +23,7 @@
 
 struct fpm_globals_s fpm_globals;
 
-int fpm_init(int argc, char **argv, char *config, char *prefix, int test_conf, struct event_base **base) /* {{{ */
+int fpm_init(int argc, char **argv, char *config, char *prefix, int test_conf) /* {{{ */
 {
        fpm_globals.argc = argc;
        fpm_globals.argv = argv;
@@ -40,7 +40,7 @@ int fpm_init(int argc, char **argv, char *config, char *prefix, int test_conf, s
                0 > fpm_children_init_main()         ||
                0 > fpm_sockets_init_main()          ||
                0 > fpm_worker_pool_init_main()      ||
-               0 > fpm_event_init_main(base)) {
+               0 > fpm_event_init_main()) {
                return -1;
        }
 
@@ -57,7 +57,7 @@ int fpm_init(int argc, char **argv, char *config, char *prefix, int test_conf, s
 
 /*     children: return listening socket
        parent: never return */
-int fpm_run(int *max_requests, struct event_base *base) /* {{{ */
+int fpm_run(int *max_requests) /* {{{ */
 {
        struct fpm_worker_pool_s *wp;
 
@@ -65,7 +65,7 @@ int fpm_run(int *max_requests, struct event_base *base) /* {{{ */
        for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
                int is_parent;
 
-               is_parent = fpm_children_create_initial(wp, base);
+               is_parent = fpm_children_create_initial(wp);
 
                if (!is_parent) {
                        goto run_child;
@@ -73,7 +73,7 @@ int fpm_run(int *max_requests, struct event_base *base) /* {{{ */
        }
 
        /* run event loop forever */
-       fpm_event_loop(base);
+       fpm_event_loop();
 
 run_child: /* only workers reach this point */
 
index 834f4f192984fef73c7526ba433c4920b2edc136..63e3bacca427f29860f9051dffc24fe26d80c9e6 100644 (file)
@@ -6,11 +6,9 @@
 #define FPM_H 1
 
 #include <unistd.h>
-#include <sys/types.h> /* for event.h below */
-#include <event.h>
 
-int fpm_run(int *max_requests, struct event_base *base);
-int fpm_init(int argc, char **argv, char *config, char *prefix, int test_conf, struct event_base **base);
+int fpm_run(int *max_requests);
+int fpm_init(int argc, char **argv, char *config, char *prefix, int test_conf);
 
 struct fpm_globals_s {
        pid_t parent_pid;
index fd11be4102af2c3bfade8e32a8bdc613ad548a26..499ad08e8f2afdc414ea1ebe8ded4646dc08cfab 100644 (file)
@@ -171,7 +171,7 @@ int fpm_children_free(struct fpm_child_s *child) /* {{{ */
 }
 /* }}} */
 
-void fpm_children_bury(struct event_base *base) /* {{{ */
+void fpm_children_bury() /* {{{ */
 {
        int status;
        pid_t pid;
@@ -201,13 +201,13 @@ void fpm_children_bury(struct event_base *base) /* {{{ */
 
                } else if (WIFSIGNALED(status)) {
                        const char *signame = fpm_signal_names[WTERMSIG(status)];
-                       const char *have_core = WCOREDUMP(status) ? " (core dumped)" : "";
+                       const char *have_core = WCOREDUMP(status) ? " - core dumped" : "";
 
                        if (signame == NULL) {
                                signame = "";
                        }
 
-                       snprintf(buf, sizeof(buf), "on signal %d %s%s", WTERMSIG(status), signame, have_core);
+                       snprintf(buf, sizeof(buf), "on signal %d (%s%s)", WTERMSIG(status), signame, have_core);
 
                        /* if it's been killed because of dynamic process management
                         * don't restart it automaticaly
@@ -277,19 +277,19 @@ void fpm_children_bury(struct event_base *base) /* {{{ */
 
                                        zlog(ZLOG_WARNING, "failed processes threshold (%d in %d sec) is reached, initiating reload", fpm_global_config.emergency_restart_threshold, fpm_global_config.emergency_restart_interval);
 
-                                       fpm_pctl(FPM_PCTL_STATE_RELOADING, FPM_PCTL_ACTION_SET, base);
+                                       fpm_pctl(FPM_PCTL_STATE_RELOADING, FPM_PCTL_ACTION_SET);
                                }
                        }
 
                        if (restart_child) {
-                               fpm_children_make(wp, 1 /* in event loop */, 1, 0, base);
+                               fpm_children_make(wp, 1 /* in event loop */, 1, 0);
 
                                if (fpm_globals.is_child) {
                                        break;
                                }
                        }
                } else {
-                       zlog(ZLOG_ALERT, "oops, unknown child exited %s", buf);
+                       zlog(ZLOG_ALERT, "oops, unknown child (%d) exited %s", pid, buf);
                }
        }
 }
@@ -340,15 +340,15 @@ static void fpm_child_resources_use(struct fpm_child_s *child) /* {{{ */
 }
 /* }}} */
 
-static void fpm_parent_resources_use(struct fpm_child_s *child, struct event_base *base) /* {{{ */
+static void fpm_parent_resources_use(struct fpm_child_s *child) /* {{{ */
 {
        fpm_shm_slots_parent_use_slot(child);
-       fpm_stdio_parent_use_pipes(child, base);
+       fpm_stdio_parent_use_pipes(child);
        fpm_child_link(child);
 }
 /* }}} */
 
-int fpm_children_make(struct fpm_worker_pool_s *wp, int in_event_loop, int nb_to_spawn, int is_debug, struct event_base *base) /* {{{ */
+int fpm_children_make(struct fpm_worker_pool_s *wp, int in_event_loop, int nb_to_spawn, int is_debug) /* {{{ */
 {
        int enough = 0;
        pid_t pid;
@@ -378,12 +378,8 @@ int fpm_children_make(struct fpm_worker_pool_s *wp, int in_event_loop, int nb_to
                switch (pid) {
 
                        case 0 :
-                               event_reinit(base); /* reinitialize event base after fork() */
                                fpm_child_resources_use(child);
                                fpm_globals.is_child = 1;
-                               if (in_event_loop) {
-                                       fpm_event_exit_loop(base);
-                               }
                                fpm_child_init(wp);
                                return 0;
 
@@ -398,7 +394,7 @@ int fpm_children_make(struct fpm_worker_pool_s *wp, int in_event_loop, int nb_to
                        default :
                                child->pid = pid;
                                fpm_clock_get(&child->started);
-                               fpm_parent_resources_use(child, base);
+                               fpm_parent_resources_use(child);
 
                                zlog(is_debug ? ZLOG_DEBUG : ZLOG_NOTICE, "[pool %s] child %d started", wp->config->name, (int) pid);
                }
@@ -409,9 +405,9 @@ int fpm_children_make(struct fpm_worker_pool_s *wp, int in_event_loop, int nb_to
 }
 /* }}} */
 
-int fpm_children_create_initial(struct fpm_worker_pool_s *wp, struct event_base *base) /* {{{ */
+int fpm_children_create_initial(struct fpm_worker_pool_s *wp) /* {{{ */
 {
-       return fpm_children_make(wp, 0 /* not in event loop yet */, 0, 1, base);
+       return fpm_children_make(wp, 0 /* not in event loop yet */, 0, 1);
 }
 /* }}} */
 
index d8818426905dc8cc92d053d079d838af15ef898b..4010a4f3b82c00193468277ff219a94af340ed16 100644 (file)
@@ -7,15 +7,15 @@
 
 #include <sys/time.h>
 #include <sys/types.h>
-#include <event.h>
 
 #include "fpm_worker_pool.h"
+#include "fpm_events.h"
 
-int fpm_children_create_initial(struct fpm_worker_pool_s *wp, struct event_base *base);
+int fpm_children_create_initial(struct fpm_worker_pool_s *wp);
 int fpm_children_free(struct fpm_child_s *child);
-void fpm_children_bury(struct event_base *base);
+void fpm_children_bury();
 int fpm_children_init_main();
-int fpm_children_make(struct fpm_worker_pool_s *wp, int in_event_loop, int nb_to_spawn, int is_debug, struct event_base *base);
+int fpm_children_make(struct fpm_worker_pool_s *wp, int in_event_loop, int nb_to_spawn, int is_debug);
 
 struct fpm_child_s;
 
@@ -23,7 +23,7 @@ struct fpm_child_s {
        struct fpm_child_s *prev, *next;
        struct timeval started;
        struct fpm_worker_pool_s *wp;
-       struct event ev_stdout, ev_stderr;
+       struct fpm_event_s ev_stdout, ev_stderr;
        int shm_slot_i;
        int fd_stdout, fd_stderr;
        void (*tracer)(struct fpm_child_s *);
index dcc0ce5f623621d8da9a482c54f8e10a3745a31c..66ff393e2f059ef07cc795743addb7b70da2f424 100644 (file)
@@ -9,6 +9,9 @@
 #include <stdlib.h> /* for putenv */
 #include <string.h>
 
+#include <php.h>
+#include <php_network.h>
+
 #include "fpm.h"
 #include "fpm_process_ctl.h"
 #include "fpm_events.h"
 #include "fpm_signals.h"
 #include "fpm_children.h"
 #include "zlog.h"
+#include "fpm_clock.h"
+
+#define fpm_event_set_timeout(ev, now) timeradd(&(now), &(ev)->frequency, &(ev)->timeout);
+
+typedef struct fpm_event_queue_s {
+       struct fpm_event_queue_s *prev;
+       struct fpm_event_queue_s *next;
+       struct fpm_event_s *ev;
+} fpm_event_queue;
+
+static void fpm_event_cleanup(int which, void *arg);
+static void fpm_got_signal(struct fpm_event_s *ev, short which, void *arg);
+static struct fpm_event_s *fpm_event_queue_isset(struct fpm_event_queue_s *queue, struct fpm_event_s *ev);
+static int fpm_event_queue_add(struct fpm_event_queue_s **queue, struct fpm_event_s *ev);
+static int fpm_event_queue_del(struct fpm_event_queue_s **queue, struct fpm_event_s *ev);
+static void fpm_event_queue_destroy(struct fpm_event_queue_s **queue);
+
+static int fpm_event_nfds_max;
+static struct fpm_event_queue_s *fpm_event_queue_timer = NULL;
+static struct fpm_event_queue_s *fpm_event_queue_fd = NULL;
+static php_pollfd *fpm_event_ufds = NULL;
 
 static void fpm_event_cleanup(int which, void *arg) /* {{{ */
 {
-       struct event_base *base = (struct event_base *)arg;
-       event_base_free(base);
+       if (fpm_event_ufds) {
+               free(fpm_event_ufds);
+       }
+       fpm_event_queue_destroy(&fpm_event_queue_timer);
+       fpm_event_queue_destroy(&fpm_event_queue_fd);
 }
 /* }}} */
 
-static void fpm_got_signal(int fd, short ev, void *arg) /* {{{ */
+static void fpm_got_signal(struct fpm_event_s *ev, short which, void *arg) /* {{{ */
 {
        char c;
        int res;
-       struct event_base *base = (struct event_base *)arg;
+       int fd = ev->fd;;
 
        do {
                do {
@@ -46,22 +73,22 @@ static void fpm_got_signal(int fd, short ev, void *arg) /* {{{ */
                switch (c) {
                        case 'C' :                  /* SIGCHLD */
                                zlog(ZLOG_DEBUG, "received SIGCHLD");
-                               fpm_children_bury(base);
+                               fpm_children_bury();
                                break;
                        case 'I' :                  /* SIGINT  */
                                zlog(ZLOG_DEBUG, "received SIGINT");
                                zlog(ZLOG_NOTICE, "Terminating ...");
-                               fpm_pctl(FPM_PCTL_STATE_TERMINATING, FPM_PCTL_ACTION_SET, base);
+                               fpm_pctl(FPM_PCTL_STATE_TERMINATING, FPM_PCTL_ACTION_SET);
                                break;
                        case 'T' :                  /* SIGTERM */
                                zlog(ZLOG_DEBUG, "received SIGTERM");
                                zlog(ZLOG_NOTICE, "Terminating ...");
-                               fpm_pctl(FPM_PCTL_STATE_TERMINATING, FPM_PCTL_ACTION_SET, base);
+                               fpm_pctl(FPM_PCTL_STATE_TERMINATING, FPM_PCTL_ACTION_SET);
                                break;
                        case 'Q' :                  /* SIGQUIT */
                                zlog(ZLOG_DEBUG, "received SIGQUIT");
                                zlog(ZLOG_NOTICE, "Finishing ...");
-                               fpm_pctl(FPM_PCTL_STATE_FINISHING, FPM_PCTL_ACTION_SET, base);
+                               fpm_pctl(FPM_PCTL_STATE_FINISHING, FPM_PCTL_ACTION_SET);
                                break;
                        case '1' :                  /* SIGUSR1 */
                                zlog(ZLOG_DEBUG, "received SIGUSR1");
@@ -74,7 +101,7 @@ static void fpm_got_signal(int fd, short ev, void *arg) /* {{{ */
                        case '2' :                  /* SIGUSR2 */
                                zlog(ZLOG_DEBUG, "received SIGUSR2");
                                zlog(ZLOG_NOTICE, "Reloading in progress ...");
-                               fpm_pctl(FPM_PCTL_STATE_RELOADING, FPM_PCTL_ACTION_SET, base);
+                               fpm_pctl(FPM_PCTL_STATE_RELOADING, FPM_PCTL_ACTION_SET);
                                break;
                }
 
@@ -86,57 +113,335 @@ static void fpm_got_signal(int fd, short ev, void *arg) /* {{{ */
 }
 /* }}} */
 
-int fpm_event_init_main(struct event_base **base) /* {{{ */
+static struct fpm_event_s *fpm_event_queue_isset(struct fpm_event_queue_s *queue, struct fpm_event_s *ev) /* {{{ */
+{
+       if (!ev) {
+               return NULL;
+       }
+
+       while (queue) {
+               if (queue->ev == ev) {
+                       return ev;
+               }
+               queue = queue->next;
+       }
+
+       return NULL;
+}
+/* }}} */
+
+static int fpm_event_queue_add(struct fpm_event_queue_s **queue, struct fpm_event_s *ev) /* {{{ */
+{
+       struct fpm_event_queue_s *elt;
+
+       if (!queue || !ev) {
+               return -1;
+       }
+
+       if (fpm_event_queue_isset(*queue, ev)) {
+               return 0;
+       }
+
+       if (!(elt = malloc(sizeof(struct fpm_event_queue_s)))) {
+               zlog(ZLOG_SYSERROR, "malloc() failed");
+               return -1;
+       }
+       elt->prev = NULL;
+       elt->next = NULL;
+       elt->ev = ev;
+
+       if (*queue) {
+               (*queue)->prev = elt;
+               elt->next = *queue;
+       }
+       *queue = elt;
+
+       return 0;       
+}
+/* }}} */
+
+static int fpm_event_queue_del(struct fpm_event_queue_s **queue, struct fpm_event_s *ev) /* {{{ */
+{
+       struct fpm_event_queue_s *q;
+       if (!queue || !ev) {
+               return -1;
+       }
+       q = *queue;
+       while (q) {
+               if (q->ev == ev) {
+                       if (q->prev) {
+                               q->prev->next = q->next;
+                       }
+                       if (q->next) {
+                               q->next->prev = q->prev;
+                       }
+                       if (q == *queue) {
+                               *queue = q->next;
+                               (*queue)->prev = NULL;
+                       }
+                       free(q);
+                       return 0;
+               }
+               q = q->next;
+       }
+       return -1;
+}
+/* }}} */
+
+static void fpm_event_queue_destroy(struct fpm_event_queue_s **queue) /* {{{ */
+{
+       struct fpm_event_queue_s *q, *tmp;
+
+       if (!queue) {
+               return;
+       }
+       q = *queue;
+       while (q) {
+               tmp = q;
+               q = q->next;
+               /* q->prev = NULL */
+               free(tmp);
+       }
+       *queue = NULL;
+}
+/* }}} */
+
+int fpm_event_init_main() /* {{{ */
 {
-       *base = event_base_new();
+       struct fpm_worker_pool_s *wp;
+
+       /* count the max number of necessary fds for polling */
+       fpm_event_nfds_max = 1; /* only one FD is necessary at startup for the master process signal pipe */
+       for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
+               if (!wp->config) continue;
+               if (wp->config->catch_workers_output && wp->config->pm_max_children > 0) {
+                       fpm_event_nfds_max += (wp->config->pm_max_children * 2);
+               }
+       }
 
-       zlog(ZLOG_DEBUG, "libevent %s: using %s", event_get_version(), event_base_get_method(*base));
+       /* malloc the max number of necessary fds for polling */
+       fpm_event_ufds = malloc(sizeof(php_pollfd) * fpm_event_nfds_max);
+       if (!fpm_event_ufds) {
+               zlog(ZLOG_SYSERROR, "malloc() failed");
+               return -1;
+       }
 
-       if (0 > fpm_cleanup_add(FPM_CLEANUP_ALL, fpm_event_cleanup, *base)) {
+       zlog(ZLOG_DEBUG, "%d fds have been reserved", fpm_event_nfds_max);
+
+       if (0 > fpm_cleanup_add(FPM_CLEANUP_ALL, fpm_event_cleanup, NULL)) {
                return -1;
        }
        return 0;
 }
 /* }}} */
 
-int fpm_event_loop(struct event_base *base) /* {{{ */
+void fpm_event_loop() /* {{{ */
 {
-       static struct event signal_fd_event;
+       static struct fpm_event_s signal_fd_event;
+
+       /* sanity check */
+       if (fpm_globals.parent_pid != getpid()) {
+               return;
+       }
+
+       fpm_event_set(&signal_fd_event, fpm_signals_get_fd(), FPM_EV_READ, &fpm_got_signal, NULL);
+       fpm_event_add(&signal_fd_event, 0);
+
+       /* add timers */
+       fpm_pctl_heartbeat(NULL, 0, NULL);
+       fpm_pctl_perform_idle_server_maintenance_heartbeat(NULL, 0, NULL);
 
-       event_set(&signal_fd_event, fpm_signals_get_fd(), EV_PERSIST | EV_READ, &fpm_got_signal, base);
-       event_base_set(base, &signal_fd_event);
-       event_add(&signal_fd_event, 0);
-       fpm_pctl_heartbeat(-1, 0, base);
-       fpm_pctl_perform_idle_server_maintenance_heartbeat(-1, 0, base);
        zlog(ZLOG_NOTICE, "ready to handle connections");
-       event_base_dispatch(base);
-       return 0;
+
+       while (1) {
+               struct fpm_event_queue_s *q, *q2;
+               struct timeval ms;
+               struct timeval tmp;
+               struct timeval now;
+               unsigned long int timeout;
+               int i, ret;
+
+               /* sanity check */
+               if (fpm_globals.parent_pid != getpid()) {
+                       return;
+               }
+
+               fpm_clock_get(&now);
+               timerclear(&ms);
+
+               /* search in the timeout queue for the next timer to trigger */
+               q = fpm_event_queue_timer;
+               while (q) {
+                       if (!timerisset(&ms)) {
+                               ms = q->ev->timeout;
+                       } else {
+                               if (timercmp(&q->ev->timeout, &ms, <)) {
+                                       ms = q->ev->timeout;
+                               }
+                       }
+                       q = q->next;
+               }
+
+               /* 1s timeout if none has been set */
+               if (!timerisset(&ms) || timercmp(&ms, &now, <) || timercmp(&ms, &now, ==)) {
+                       timeout = 1000;
+               } else {
+                       timersub(&ms, &now, &tmp);
+                       timeout = (tmp.tv_sec * 1000) + (tmp.tv_usec / 1000) + 1;
+               }
+
+               /* init fpm_event_ufds for php_poll2 */
+               memset(fpm_event_ufds, 0, sizeof(php_pollfd) * fpm_event_nfds_max);
+               i = 0;
+               q = fpm_event_queue_fd;
+               while (q && i < fpm_event_nfds_max) {
+                       fpm_event_ufds[i].fd = q->ev->fd;
+                       fpm_event_ufds[i].events = POLLIN;
+                       q->ev->index = i++;
+                       q = q->next;
+               }
+
+               /* wait for inconming event or timeout */
+               if ((ret = php_poll2(fpm_event_ufds, i, timeout)) == -1) {
+                       if (errno != EINTR) {
+                               zlog(ZLOG_WARNING, "php_poll2() returns %d", errno);
+                       }
+               } else if (ret > 0) {
+
+                       /* trigger POLLIN events */
+                       q = fpm_event_queue_fd;
+                       while (q) {
+                               if (q->ev && q->ev->index >= 0 && q->ev->index < fpm_event_nfds_max) {
+                                       if (q->ev->fd == fpm_event_ufds[q->ev->index].fd) {
+                                               if (fpm_event_ufds[q->ev->index].revents & POLLIN) {
+                                                       fpm_event_fire(q->ev);
+                                                       /* sanity check */
+                                                       if (fpm_globals.parent_pid != getpid()) {
+                                                               return;
+                                                       }
+                                               }
+                                       }
+                                       q->ev->index = -1;
+                               }
+                               q = q->next;
+                       }
+               }
+
+               /* trigger timers */
+               q = fpm_event_queue_timer;
+               while (q) {
+                       fpm_clock_get(&now);
+                       if (q->ev) {
+                               if (timercmp(&now, &q->ev->timeout, >) || timercmp(&now, &q->ev->timeout, ==)) {
+                                       fpm_event_fire(q->ev);
+                                       /* sanity check */
+                                       if (fpm_globals.parent_pid != getpid()) {
+                                               return;
+                                       }
+                                       if (q->ev->flags & FPM_EV_PERSIST) {
+                                               fpm_event_set_timeout(q->ev, now);
+                                       } else { /* delete the event */
+                                               q2 = q;
+                                               if (q->prev) {
+                                                       q->prev->next = q->next;
+                                               }
+                                               if (q->next) {
+                                                       q->next->prev = q->prev;
+                                               }
+                                               if (q == fpm_event_queue_timer) {
+                                                       fpm_event_queue_timer = q->next;
+                                                       fpm_event_queue_timer->prev = NULL;
+                                               }
+                                               q = q->next;
+                                               free(q2);
+                                               continue;
+                                       }
+                               }
+                       }
+                       q = q->next;
+               }
+       }
 }
 /* }}} */
 
-int fpm_event_add(int fd, struct event_base *base, struct event *ev, void (*callback)(int, short, void *), void *arg) /* {{{ */
+void fpm_event_fire(struct fpm_event_s *ev) /* {{{ */
 {
-       event_set(ev, fd, EV_PERSIST | EV_READ, callback, arg);
-       event_base_set(base, ev);
-       return event_add(ev, 0);
+       if (!ev || !ev->callback) {
+               return;
+       }
+
+       (*ev->callback)( (struct fpm_event_s *) ev, ev->which, ev->arg);        
 }
 /* }}} */
 
-int fpm_event_del(struct event *ev) /* {{{ */
+int fpm_event_set(struct fpm_event_s *ev, int fd, int flags, void (*callback)(struct fpm_event_s *, short, void *), void *arg) /* {{{ */
 {
-       return event_del(ev);
+       if (!ev || !callback || fd < -1) {
+               return -1;
+       }
+       memset(ev, 0, sizeof(struct fpm_event_s));
+       ev->fd = fd;
+       ev->callback = callback;
+       ev->arg = arg;
+       ev->flags = flags;
+       return 0;
 }
 /* }}} */
 
-void fpm_event_exit_loop(struct event_base *base) /* {{{ */
+int fpm_event_add(struct fpm_event_s *ev, unsigned long int frequency) /* {{{ */
 {
-       event_base_loopbreak(base);
+       struct timeval now;
+       struct timeval tmp;
+
+       if (!ev) {
+               return -1;
+       }
+
+       ev->index = -1;
+
+       /* it's a triggered event on incoming data */
+       if (ev->flags & FPM_EV_READ) {
+               ev->which = FPM_EV_READ;
+               if (fpm_event_queue_add(&fpm_event_queue_fd, ev) != 0) {
+                       return -1;
+               }
+               return 0;
+       }
+
+       /* it's a timer event */
+       ev->which = FPM_EV_TIMEOUT;
+
+       fpm_clock_get(&now);
+       if (frequency >= 1000) {
+               tmp.tv_sec = frequency / 1000;
+               tmp.tv_usec = (frequency % 1000) * 1000;
+       } else {
+               tmp.tv_sec = 0;
+               tmp.tv_usec = frequency * 1000;
+       }
+       ev->frequency = tmp;
+       fpm_event_set_timeout(ev, now);
+
+       if (fpm_event_queue_add(&fpm_event_queue_timer, ev) != 0) {
+               return -1;
+       }
+
+       return 0;
 }
 /* }}} */
 
-void fpm_event_fire(struct event *ev) /* {{{ */
+int fpm_event_del(struct fpm_event_s *ev) /* {{{ */
 {
-       (*ev->ev_callback)( (int) ev->ev_fd, (short) ev->ev_res, ev->ev_arg);   
+       if (fpm_event_queue_del(&fpm_event_queue_fd, ev) != 0) {
+               return -1;
+       }
+
+       if (fpm_event_queue_del(&fpm_event_queue_timer, ev) != 0) {
+               return -1;
+       }
+
+       return 0;
 }
 /* }}} */
 
+/* }}} */
index 7a5a9a53b0bf22d894307feb4fec9198130ea60f..bec13ba5e7665b2cfccf905934825c4e9f6bff2e 100644 (file)
@@ -5,12 +5,28 @@
 #ifndef FPM_EVENTS_H
 #define FPM_EVENTS_H 1
 
-void fpm_event_exit_loop(struct event_base *base);
-int fpm_event_loop(struct event_base *base);
-int fpm_event_add(int fd, struct event_base *base, struct event *ev, void (*callback)(int, short, void *), void *arg);
-int fpm_event_del(struct event *ev);
-void fpm_event_fire(struct event *ev);
-int fpm_event_init_main(struct event_base **base);
+#define FPM_EV_TIMEOUT  (1 << 0)
+#define FPM_EV_READ     (1 << 1)
+#define FPM_EV_PERSIST  (1 << 2)
 
+#define fpm_event_set_timer(ev, flags, cb, arg) fpm_event_set((ev), -1, (flags), (cb), (arg))
+
+struct fpm_event_s {
+       int fd;                   /* not set with FPM_EV_TIMEOUT */
+       struct timeval timeout;   /* next time to trigger */
+       struct timeval frequency;
+       void (*callback)(struct fpm_event_s *, short, void *);
+       void *arg;
+       int flags;
+       int index;                /* index of the fd in the ufds array */
+       short which;              /* type of event */
+};
+
+void fpm_event_loop();
+void fpm_event_fire(struct fpm_event_s *ev);
+int fpm_event_init_main();
+int fpm_event_set(struct fpm_event_s *ev, int fd, int flags, void (*callback)(struct fpm_event_s *, short, void *), void *arg);
+int fpm_event_add(struct fpm_event_s *ev, unsigned long int timeout);
+int fpm_event_del(struct fpm_event_s *ev);
 
 #endif
index a0672fd01770f7b66fb113addf0abf1a959afd3b..8f0d7600748505ec6759fe88091d41bd83c1f4d2 100644 (file)
@@ -168,7 +168,6 @@ typedef struct _php_cgi_globals_struct {
        HashTable user_config_cache;
        char *error_header;
        char *fpm_config;
-       struct event_base *event_base;
 } php_cgi_globals_struct;
 
 /* {{{ user_config_cache
@@ -1780,11 +1779,11 @@ consult the installation file that came with this distribution, or visit \n\
                }
        }
 
-       if (0 > fpm_init(argc, argv, fpm_config ? fpm_config : CGIG(fpm_config), fpm_prefix, test_conf, &CGIG(event_base))) {
+       if (0 > fpm_init(argc, argv, fpm_config ? fpm_config : CGIG(fpm_config), fpm_prefix, test_conf)) {
                return FAILURE;
        }
 
-       fcgi_fd = fpm_run(&max_requests, CGIG(event_base));
+       fcgi_fd = fpm_run(&max_requests);
        parent = 0;
        fcgi_set_is_fastcgi(1);
 
index 367c041b3d4944f5eecb9c625e171e8ba918abd3..badda1408237b1a01bf1f13e2acb873de508044b 100644 (file)
@@ -49,29 +49,18 @@ static void fpm_pctl_cleanup(int which, void *arg) /* {{{ */
 }
 /* }}} */
 
-static struct event pctl_event;
+static struct fpm_event_s pctl_event;
 
-static void fpm_pctl_action(int fd, short which, void *arg) /* {{{ */
+static void fpm_pctl_action(struct fpm_event_s *ev, short which, void *arg) /* {{{ */
 {
-       struct event_base *base = (struct event_base *)arg;
-
-       evtimer_del(&pctl_event);
-       memset(&pctl_event, 0, sizeof(pctl_event));
-       fpm_pctl(FPM_PCTL_STATE_UNSPECIFIED, FPM_PCTL_ACTION_TIMEOUT, base);
+       fpm_pctl(FPM_PCTL_STATE_UNSPECIFIED, FPM_PCTL_ACTION_TIMEOUT);
 }
 /* }}} */
 
-static int fpm_pctl_timeout_set(int sec, struct event_base *base) /* {{{ */
+static int fpm_pctl_timeout_set(int sec) /* {{{ */
 {
-       struct timeval tv = { .tv_sec = sec, .tv_usec = 0 };
-
-       if (evtimer_initialized(&pctl_event)) {
-               evtimer_del(&pctl_event);
-       }
-
-       evtimer_set(&pctl_event, &fpm_pctl_action, base);
-       event_base_set(base, &pctl_event);
-       evtimer_add(&pctl_event, &tv);
+       fpm_event_set_timer(&pctl_event, 0, &fpm_pctl_action, NULL);
+       fpm_event_add(&pctl_event, sec * 1000);
        return 0;
 }
 /* }}} */
@@ -181,7 +170,7 @@ static void fpm_pctl_kill_all(int signo) /* {{{ */
 }
 /* }}} */
 
-static void fpm_pctl_action_next(struct event_base *base) /* {{{ */
+static void fpm_pctl_action_next() /* {{{ */
 {
        int sig, timeout;
 
@@ -207,11 +196,11 @@ static void fpm_pctl_action_next(struct event_base *base) /* {{{ */
 
        fpm_pctl_kill_all(sig);
        fpm_signal_sent = sig;
-       fpm_pctl_timeout_set(timeout, base);
+       fpm_pctl_timeout_set(timeout);
 }
 /* }}} */
 
-void fpm_pctl(int new_state, int action, struct event_base *base) /* {{{ */
+void fpm_pctl(int new_state, int action) /* {{{ */
 {
        switch (action) {
                case FPM_PCTL_ACTION_SET :
@@ -243,7 +232,7 @@ void fpm_pctl(int new_state, int action, struct event_base *base) /* {{{ */
                        /* fall down */
 
                case FPM_PCTL_ACTION_TIMEOUT :
-                       fpm_pctl_action_next(base);
+                       fpm_pctl_action_next();
                        break;
                case FPM_PCTL_ACTION_LAST_CHILD_EXITED :
                        fpm_pctl_action_last();
@@ -259,14 +248,14 @@ int fpm_pctl_can_spawn_children() /* {{{ */
 }
 /* }}} */
 
-int fpm_pctl_child_exited(struct event_base *base) /* {{{ */
+int fpm_pctl_child_exited() /* {{{ */
 {
        if (fpm_state == FPM_PCTL_STATE_NORMAL) {
                return 0;
        }
 
        if (!fpm_globals.running_children) {
-               fpm_pctl(FPM_PCTL_STATE_UNSPECIFIED, FPM_PCTL_ACTION_LAST_CHILD_EXITED, base);
+               fpm_pctl(FPM_PCTL_STATE_UNSPECIFIED, FPM_PCTL_ACTION_LAST_CHILD_EXITED);
        }
        return 0;
 }
@@ -318,7 +307,7 @@ static void fpm_pctl_check_request_timeout(struct timeval *now) /* {{{ */
 }
 /* }}} */
 
-static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now, struct event_base *base) /* {{{ */
+static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{ */
 {
        struct fpm_worker_pool_s *wp;
 
@@ -396,7 +385,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now, struct
                        }
                        wp->warn_max_children = 0;
 
-                       fpm_children_make(wp, 1, children_to_fork, 1, base);
+                       fpm_children_make(wp, 1, children_to_fork, 1);
 
                        /* if it's a child, stop here without creating the next event
                         * this event is reserved to the master process
@@ -418,37 +407,40 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now, struct
 }
 /* }}} */
 
-void fpm_pctl_heartbeat(int fd, short which, void *arg) /* {{{ */
+void fpm_pctl_heartbeat(struct fpm_event_s *ev, short which, void *arg) /* {{{ */
 {
-       static struct event heartbeat;
-       struct timeval tv = { .tv_sec = 0, .tv_usec = 130000 };
+       static struct fpm_event_s heartbeat;
        struct timeval now;
-       struct event_base *base = (struct event_base *)arg;
 
-       if (which == EV_TIMEOUT) {
-               evtimer_del(&heartbeat);
+       if (fpm_globals.parent_pid != getpid()) {
+               return; /* sanity check */
+       }
+
+       if (which == FPM_EV_TIMEOUT) {
                fpm_clock_get(&now);
                fpm_pctl_check_request_timeout(&now);
+               return;
        }
 
-       evtimer_set(&heartbeat, &fpm_pctl_heartbeat, base);
-       event_base_set(base, &heartbeat);
-       evtimer_add(&heartbeat, &tv);
+       /* first call without setting to initialize the timer */
+       fpm_event_set_timer(&heartbeat, FPM_EV_PERSIST, &fpm_pctl_heartbeat, NULL);
+       fpm_event_add(&heartbeat, FPM_PCTL_HEARTBEAT);
 }
 /* }}} */
 
-void fpm_pctl_perform_idle_server_maintenance_heartbeat(int fd, short which, void *arg) /* {{{ */
+void fpm_pctl_perform_idle_server_maintenance_heartbeat(struct fpm_event_s *ev, short which, void *arg) /* {{{ */
 {
-       static struct event heartbeat;
-       struct timeval tv = { .tv_sec = 0, .tv_usec = FPM_IDLE_SERVER_MAINTENANCE_HEARTBEAT };
+       static struct fpm_event_s heartbeat;
        struct timeval now;
-       struct event_base *base = (struct event_base *)arg;
 
-       if (which == EV_TIMEOUT) {
-               evtimer_del(&heartbeat);
+       if (fpm_globals.parent_pid != getpid()) {
+               return; /* sanity check */
+       }
+
+       if (which == FPM_EV_TIMEOUT) {
                fpm_clock_get(&now);
                if (fpm_pctl_can_spawn_children()) {
-                       fpm_pctl_perform_idle_server_maintenance(&now, base);
+                       fpm_pctl_perform_idle_server_maintenance(&now);
 
                        /* if it's a child, stop here without creating the next event
                         * this event is reserved to the master process
@@ -457,11 +449,12 @@ void fpm_pctl_perform_idle_server_maintenance_heartbeat(int fd, short which, voi
                                return;
                        }
                }
+               return;
        }
 
-       evtimer_set(&heartbeat, &fpm_pctl_perform_idle_server_maintenance_heartbeat, base);
-       event_base_set(base, &heartbeat);
-       evtimer_add(&heartbeat, &tv);
+       /* first call without setting which to initialize the timer */
+       fpm_event_set_timer(&heartbeat, FPM_EV_PERSIST, &fpm_pctl_perform_idle_server_maintenance_heartbeat, NULL);
+       fpm_event_add(&heartbeat, FPM_IDLE_SERVER_MAINTENANCE_HEARTBEAT);
 }
 /* }}} */
 
index 0c8801f69bdfbe1b0e005d416ebd4083f5411145..36577097cbddc529ed47d76fcbc5ad5de6bb21eb 100644 (file)
@@ -5,18 +5,22 @@
 #ifndef FPM_PROCESS_CTL_H
 #define FPM_PROCESS_CTL_H 1
 
+#include "fpm_events.h"
+
 /* spawn max 32 children at once */
 #define FPM_MAX_SPAWN_RATE (32)
-/* 1s (in µs here)  heatbeat for idle server maintenance */
-#define FPM_IDLE_SERVER_MAINTENANCE_HEARTBEAT (1000000)
+/* 1s (in ms) heartbeat for idle server maintenance */
+#define FPM_IDLE_SERVER_MAINTENANCE_HEARTBEAT (1000)
+/* 130ms heartbeat for pctl */
+#define FPM_PCTL_HEARTBEAT (130)
 
 struct fpm_child_s;
 
-void fpm_pctl(int new_state, int action, struct event_base *base);
+void fpm_pctl(int new_state, int action);
 int fpm_pctl_can_spawn_children();
 int fpm_pctl_kill(pid_t pid, int how);
-void fpm_pctl_heartbeat(int fd, short which, void *arg);
-void fpm_pctl_perform_idle_server_maintenance_heartbeat(int fd, short which, void *arg);
+void fpm_pctl_heartbeat(struct fpm_event_s *ev, short which, void *arg);
+void fpm_pctl_perform_idle_server_maintenance_heartbeat(struct fpm_event_s *ev, short which, void *arg);
 int fpm_pctl_child_exited();
 int fpm_pctl_init_main();
 
index e6ecf1a6b54c1a1c0ab279e7fbf5f80308fc36bf..571f3074b53afe3ad3fad4b2817679b4284af875 100644 (file)
@@ -71,18 +71,30 @@ int fpm_stdio_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
 }
 /* }}} */
 
-static void fpm_stdio_child_said(int fd, short which, void *arg) /* {{{ */
+static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg) /* {{{ */
 {
        static const int max_buf_size = 1024;
+       int fd = ev->fd;
        char buf[max_buf_size];
-       struct fpm_child_s *child = arg;
-       int is_stdout = fd == child->fd_stdout;
-       struct event *ev = is_stdout ? &child->ev_stdout : &child->ev_stderr;
+       struct fpm_child_s *child;
+       int is_stdout;
+       struct fpm_event_s *event;
        int fifo_in = 1, fifo_out = 1;
        int is_last_message = 0;
        int in_buf = 0;
        int res;
 
+       if (!arg) {
+               return;
+       }
+       child = (struct fpm_child_s *)arg;
+       is_stdout = (fd == child->fd_stdout);
+       if (is_stdout) {
+               event = &child->ev_stdout;
+       } else {
+               event = &child->ev_stderr;
+       }
+
        while (fifo_in || fifo_out) {
                if (fifo_in) {
                        res = read(fd, buf + in_buf, max_buf_size - 1 - in_buf);
@@ -96,7 +108,7 @@ static void fpm_stdio_child_said(int fd, short which, void *arg) /* {{{ */
                                                zlog(ZLOG_SYSERROR, "read() failed");
                                        }
 
-                                       fpm_event_del(ev);
+                                       fpm_event_del(event);
                                        is_last_message = 1;
 
                                        if (is_stdout) {
@@ -183,7 +195,7 @@ int fpm_stdio_prepare_pipes(struct fpm_child_s *child) /* {{{ */
 }
 /* }}} */
 
-int fpm_stdio_parent_use_pipes(struct fpm_child_s *child, struct event_base *base) /* {{{ */
+int fpm_stdio_parent_use_pipes(struct fpm_child_s *child) /* {{{ */
 {
        if (0 == child->wp->config->catch_workers_output) { /* not required */
                return 0;
@@ -195,8 +207,11 @@ int fpm_stdio_parent_use_pipes(struct fpm_child_s *child, struct event_base *bas
        child->fd_stdout = fd_stdout[0];
        child->fd_stderr = fd_stderr[0];
 
-       fpm_event_add(child->fd_stdout, base, &child->ev_stdout, fpm_stdio_child_said, child);
-       fpm_event_add(child->fd_stderr, base, &child->ev_stderr, fpm_stdio_child_said, child);
+       fpm_event_set(&child->ev_stdout, child->fd_stdout, FPM_EV_READ, fpm_stdio_child_said, child);
+       fpm_event_add(&child->ev_stdout, 0);
+
+       fpm_event_set(&child->ev_stderr, child->fd_stderr, FPM_EV_READ, fpm_stdio_child_said, child);
+       fpm_event_add(&child->ev_stderr, 0);
        return 0;
 }
 /* }}} */
index 5d53a26e883c2855badd42c0a33196783f53af0c..d3d61e46be2dff1ea7bc2ff4757483455a7432fd 100644 (file)
@@ -12,7 +12,7 @@ int fpm_stdio_init_final();
 int fpm_stdio_init_child(struct fpm_worker_pool_s *wp);
 int fpm_stdio_prepare_pipes(struct fpm_child_s *child);
 void fpm_stdio_child_use_pipes(struct fpm_child_s *child);
-int fpm_stdio_parent_use_pipes(struct fpm_child_s *child, struct event_base *base);
+int fpm_stdio_parent_use_pipes(struct fpm_child_s *child);
 int fpm_stdio_discard_pipes(struct fpm_child_s *child);
 int fpm_stdio_open_error_log(int reopen);
 
index 4b2b517313c68a868187b229316eeb2b2d1203b2..314b7e5c5e104179696cef9e74135aabc7140a93 100644 (file)
@@ -268,6 +268,8 @@ pm.max_children = 50
  
 ; Redirect worker stdout and stderr into main error log. If not set, stdout and
 ; stderr will be redirected to /dev/null according to FastCGI specs.
+; Note: on highloaded environement, this can cause some delay in the page
+; process time (several ms).
 ; Default Value: no
 ;catch_workers_output = yes