Back to index

php5  5.3.10
select.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Authors: Jerome Loyet <jerome@loyet.net>                             |
00016    +----------------------------------------------------------------------+
00017 */
00018 
00019 /* $Id$ */
00020 
00021 #include "../fpm_config.h"
00022 #include "../fpm_events.h"
00023 #include "../fpm.h"
00024 #include "../zlog.h"
00025 
00026 #if HAVE_SELECT
00027 
00028 /* According to POSIX.1-2001 */
00029 #include <sys/select.h>
00030 
00031 /* According to earlier standards */
00032 #include <sys/time.h>
00033 #include <sys/types.h>
00034 #include <unistd.h>
00035 
00036 #include <errno.h>
00037 
00038 static int fpm_event_select_init(int max);
00039 static int fpm_event_select_wait(struct fpm_event_queue_s *queue, unsigned long int timeout);
00040 static int fpm_event_select_add(struct fpm_event_s *ev);
00041 static int fpm_event_select_remove(struct fpm_event_s *ev);
00042 
00043 static struct fpm_event_module_s select_module = {
00044        .name = "select",
00045        .support_edge_trigger = 0,
00046        .init = fpm_event_select_init,
00047        .clean = NULL,
00048        .wait = fpm_event_select_wait,
00049        .add = fpm_event_select_add,
00050        .remove = fpm_event_select_remove,
00051 };
00052 
00053 static fd_set fds;
00054 
00055 #endif /* HAVE_SELECT */
00056 
00057 /*
00058  * return the module configuration
00059  */
00060 struct fpm_event_module_s *fpm_event_select_module() /* {{{ */
00061 {
00062 #if HAVE_SELECT
00063        return &select_module;
00064 #else
00065        return NULL;
00066 #endif /* HAVE_SELECT */
00067 }
00068 /* }}} */
00069 
00070 #if HAVE_SELECT
00071 
00072 /*
00073  * Init the module
00074  */
00075 static int fpm_event_select_init(int max) /* {{{ */
00076 {
00077        FD_ZERO(&fds);
00078        return 0;
00079 }
00080 /* }}} */
00081 
00082 
00083 /*
00084  * wait for events or timeout
00085  */
00086 static int fpm_event_select_wait(struct fpm_event_queue_s *queue, unsigned long int timeout) /* {{{ */
00087 {
00088        int ret;
00089        struct fpm_event_queue_s *q;
00090        fd_set current_fds;
00091        struct timeval t;
00092 
00093        /* copy fds because select() alters it */
00094        current_fds = fds;
00095 
00096        /* fill struct timeval with timeout */
00097        t.tv_sec = timeout / 1000;
00098        t.tv_usec = (timeout % 1000) * 1000;
00099 
00100        /* wait for inconming event or timeout */
00101        ret = select(FD_SETSIZE, &current_fds, NULL, NULL, &t);
00102        if (ret == -1) {
00103 
00104               /* trigger error unless signal interrupt */
00105               if (errno != EINTR) {
00106                      zlog(ZLOG_WARNING, "poll() returns %d", errno);
00107                      return -1;
00108               }
00109        }
00110 
00111        /* events have been triggered */
00112        if (ret > 0) {
00113 
00114               /* trigger POLLIN events */
00115               q = queue;
00116               while (q) {
00117                      if (q->ev) { /* sanity check */
00118 
00119                             /* check if the event has been triggered */
00120                             if (FD_ISSET(q->ev->fd, &current_fds)) {
00121 
00122                                    /* fire the event */
00123                                    fpm_event_fire(q->ev);
00124 
00125                                    /* sanity check */
00126                                    if (fpm_globals.parent_pid != getpid()) {
00127                                           return -2;
00128                                    }
00129                             }
00130                      }
00131                      q = q->next; /* iterate */
00132               }
00133        }
00134        return ret;
00135 
00136 }
00137 /* }}} */
00138 
00139 /*
00140  * Add a FD to the fd set
00141  */
00142 static int fpm_event_select_add(struct fpm_event_s *ev) /* {{{ */
00143 {
00144        /* check size limitation */
00145        if (ev->fd >= FD_SETSIZE) {
00146               zlog(ZLOG_ERROR, "select: not enough space in the select fd list (max = %d). Please consider using another event mechanism.", FD_SETSIZE);
00147               return -1;
00148        }
00149 
00150        /* add the FD if not already in */
00151        if (!FD_ISSET(ev->fd, &fds)) {
00152               FD_SET(ev->fd, &fds);
00153               ev->index = ev->fd;
00154        }
00155 
00156        return 0;
00157 }
00158 /* }}} */
00159 
00160 /*
00161  * Remove a FD from the fd set
00162  */
00163 static int fpm_event_select_remove(struct fpm_event_s *ev) /* {{{ */
00164 {
00165        /* remove the fd if it's in */
00166        if (FD_ISSET(ev->fd, &fds)) {
00167               FD_CLR(ev->fd, &fds);
00168               ev->index = -1;
00169        }
00170 
00171        return 0;
00172 }
00173 /* }}} */
00174 
00175 #endif /* HAVE_SELECT */