Back to index

php5  5.3.10
port.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_PORT
00027 
00028 #include <port.h>
00029 #include <poll.h>
00030 #include <errno.h>
00031 
00032 static int fpm_event_port_init(int max);
00033 static int fpm_event_port_clean();
00034 static int fpm_event_port_wait(struct fpm_event_queue_s *queue, unsigned long int timeout);
00035 static int fpm_event_port_add(struct fpm_event_s *ev);
00036 static int fpm_event_port_remove(struct fpm_event_s *ev);
00037 
00038 static struct fpm_event_module_s port_module = {
00039        .name = "port",
00040        .support_edge_trigger = 0,
00041        .init = fpm_event_port_init,
00042        .clean = fpm_event_port_clean,
00043        .wait = fpm_event_port_wait,
00044        .add = fpm_event_port_add,
00045        .remove = fpm_event_port_remove, 
00046 };
00047 
00048 port_event_t *events = NULL;
00049 int nevents = 0;
00050 static int pfd = -1;
00051 
00052 #endif /* HAVE_PORT */
00053 
00054 struct fpm_event_module_s *fpm_event_port_module() /* {{{ */
00055 {
00056 #if HAVE_PORT
00057        return &port_module;
00058 #else
00059        return NULL;
00060 #endif /* HAVE_PORT */
00061 }
00062 /* }}} */
00063 
00064 #if HAVE_PORT
00065 
00066 /*
00067  * Init the module
00068  */
00069 static int fpm_event_port_init(int max) /* {{{ */
00070 {
00071        /* open port */
00072        pfd = port_create();
00073        if (pfd < 0) {
00074               zlog(ZLOG_ERROR, "port: unable to initialize port_create()");
00075               return -1;
00076        }
00077 
00078        if (max < 1) {
00079               return 0;
00080        }
00081 
00082        /* alloc and clear active_pollfds */
00083        events = malloc(sizeof(port_event_t) * max);
00084        if (!events) {
00085               zlog(ZLOG_ERROR, "port: Unable to allocate %d events", max);
00086               return -1;
00087        }
00088 
00089        nevents = max;
00090        return 0;
00091 }
00092 /* }}} */
00093 
00094 /*
00095  * Clean the module
00096  */
00097 static int fpm_event_port_clean() /* {{{ */
00098 {
00099        if (pfd > -1) {
00100               close(pfd);
00101               pfd = -1;
00102        }
00103 
00104        if (events) {
00105               free(events);
00106               events = NULL;
00107        }
00108 
00109        nevents = 0;
00110        return 0;
00111 }
00112 /* }}} */
00113 
00114 /*
00115  * wait for events or timeout
00116  */
00117 static int fpm_event_port_wait(struct fpm_event_queue_s *queue, unsigned long int timeout) /* {{{ */
00118 {
00119        int ret, i, nget;
00120        timespec_t t;
00121 
00122        /* convert timeout into timespec_t */
00123        t.tv_sec = (int)(timeout / 1000);
00124        t.tv_nsec = (timeout % 1000) * 1000 * 1000;
00125 
00126        /* wait for inconming event or timeout. We want at least one event or timeout */
00127        nget = 1;
00128        ret = port_getn(pfd, events, nevents, &nget, &t);
00129        if (ret < 0) {
00130 
00131               /* trigger error unless signal interrupt or timeout */
00132               if (errno != EINTR && errno != ETIME) {
00133                      zlog(ZLOG_WARNING, "poll() returns %d", errno);
00134                      return -1;
00135               }
00136        }
00137 
00138        for (i = 0; i < nget; i++) {
00139 
00140               /* do we have a ptr to the event ? */
00141               if (!events[i].portev_user) {
00142                      continue;
00143               }
00144 
00145               /* fire the event */
00146               fpm_event_fire((struct fpm_event_s *)events[i].portev_user);
00147 
00148               /* sanity check */
00149               if (fpm_globals.parent_pid != getpid()) {
00150                      return -2;
00151               }
00152        }
00153        return nget;
00154 }
00155 /* }}} */
00156 
00157 /*
00158  * Add a FD to the fd set
00159  */
00160 static int fpm_event_port_add(struct fpm_event_s *ev) /* {{{ */
00161 {
00162        /* add the event to port */
00163        if (port_associate(pfd, PORT_SOURCE_FD, ev->fd, POLLIN, (void *)ev) < 0) {
00164               zlog(ZLOG_ERROR, "port: unable to add the event");
00165               return -1;
00166        }
00167        return 0;
00168 }
00169 /* }}} */
00170 
00171 /*
00172  * Remove a FD from the fd set
00173  */
00174 static int fpm_event_port_remove(struct fpm_event_s *ev) /* {{{ */
00175 {
00176        /* remove the event from port */
00177        if (port_dissociate(pfd, PORT_SOURCE_FD, ev->fd) < 0) {
00178               zlog(ZLOG_ERROR, "port: unable to add the event");
00179               return -1;
00180        }
00181        return 0;
00182 }
00183 /* }}} */
00184 
00185 #endif /* HAVE_PORT */