php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
port.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Jerome Loyet <jerome@loyet.net> |
14 +----------------------------------------------------------------------+
15*/
16
17#include "../fpm_config.h"
18#include "../fpm_events.h"
19#include "../fpm.h"
20#include "../zlog.h"
21
22#ifdef HAVE_PORT_CREATE
23
24#include <port.h>
25#include <poll.h>
26#include <errno.h>
27
28static int fpm_event_port_init(int max);
29static int fpm_event_port_clean(void);
30static int fpm_event_port_wait(struct fpm_event_queue_s *queue, unsigned long int timeout);
31static int fpm_event_port_add(struct fpm_event_s *ev);
32static int fpm_event_port_remove(struct fpm_event_s *ev);
33
34static struct fpm_event_module_s port_module = {
35 .name = "port",
36 .support_edge_trigger = 0,
37 .init = fpm_event_port_init,
38 .clean = fpm_event_port_clean,
39 .wait = fpm_event_port_wait,
40 .add = fpm_event_port_add,
41 .remove = fpm_event_port_remove,
42};
43
44port_event_t *events = NULL;
45int nevents = 0;
46static int pfd = -1;
47
48#endif /* HAVE_PORT_CREATE */
49
51{
52#ifdef HAVE_PORT_CREATE
53 return &port_module;
54#else
55 return NULL;
56#endif /* HAVE_PORT_CREATE */
57}
58/* }}} */
59
60#ifdef HAVE_PORT_CREATE
61
62/*
63 * Init the module
64 */
65static int fpm_event_port_init(int max) /* {{{ */
66{
67 /* open port */
68 pfd = port_create();
69 if (pfd < 0) {
70 zlog(ZLOG_ERROR, "port: unable to initialize port_create()");
71 return -1;
72 }
73
74 if (max < 1) {
75 return 0;
76 }
77
78 /* alloc and clear active_pollfds */
79 events = malloc(sizeof(port_event_t) * max);
80 if (!events) {
81 zlog(ZLOG_ERROR, "port: Unable to allocate %d events", max);
82 return -1;
83 }
84
85 nevents = max;
86 return 0;
87}
88/* }}} */
89
90/*
91 * Clean the module
92 */
93static int fpm_event_port_clean(void)
94{
95 if (pfd > -1) {
96 close(pfd);
97 pfd = -1;
98 }
99
100 if (events) {
101 free(events);
102 events = NULL;
103 }
104
105 nevents = 0;
106 return 0;
107}
108
109/*
110 * wait for events or timeout
111 */
112static int fpm_event_port_wait(struct fpm_event_queue_s *queue, unsigned long int timeout) /* {{{ */
113{
114 int ret;
115 unsigned int i, nget;
116 timespec_t t;
117
118 /* convert timeout into timespec_t */
119 t.tv_sec = (int)(timeout / 1000);
120 t.tv_nsec = (timeout % 1000) * 1000 * 1000;
121
122 /* wait for incoming event or timeout. We want at least one event or timeout */
123 nget = 1;
124 events[0].portev_user = (void *)-1; /* so we can double check that an event was returned */
125
126 ret = port_getn(pfd, events, nevents, &nget, &t);
127 if (ret < 0) {
128
129 /* trigger error unless signal interrupt or timeout */
130 if (errno != EINTR && errno != ETIME) {
131 zlog(ZLOG_WARNING, "poll() returns %d", errno);
132 return -1;
133 } else if (nget > 0 && events[0].portev_user == (void *)-1) {
134 /* This confusing API can return an event at the same time
135 * that it reports EINTR or ETIME. If that occurs, just
136 * report the event. With EINTR, nget can be > 0 without
137 * any event, so check that portev_user was filled in.
138 *
139 * See discussion thread
140 * http://marc.info/?l=opensolaris-networking-discuss&m=125071205204540
141 */
142 nget = 0;
143 }
144 }
145
146 for (i = 0; i < nget; i++) {
147 struct fpm_event_s *ev;
148
149 /* do we have a ptr to the event ? */
150 if (!events[i].portev_user) {
151 continue;
152 }
153
154 ev = (struct fpm_event_s *)events[i].portev_user;
155
156 /* re-associate for next event */
157 fpm_event_port_add(ev);
158
159 /* fire the event */
160 fpm_event_fire(ev);
161
162 /* sanity check */
163 if (fpm_globals.parent_pid != getpid()) {
164 return -2;
165 }
166 }
167 return nget;
168}
169/* }}} */
170
171/*
172 * Add a FD to the fd set
173 */
174static int fpm_event_port_add(struct fpm_event_s *ev) /* {{{ */
175{
176 /* add the event to port */
177 if (port_associate(pfd, PORT_SOURCE_FD, ev->fd, POLLIN, (void *)ev) < 0) {
178 zlog(ZLOG_ERROR, "port: unable to add the event");
179 return -1;
180 }
181 return 0;
182}
183/* }}} */
184
185/*
186 * Remove a FD from the fd set
187 */
188static int fpm_event_port_remove(struct fpm_event_s *ev) /* {{{ */
189{
190 /* remove the event from port */
191 if (port_dissociate(pfd, PORT_SOURCE_FD, ev->fd) < 0) {
192 zlog(ZLOG_ERROR, "port: unable to add the event");
193 return -1;
194 }
195 return 0;
196}
197/* }}} */
198
199#endif /* HAVE_PORT_CREATE */
#define max(a, b)
Definition exif.c:60
struct fpm_globals_s fpm_globals
Definition fpm.c:24
void fpm_event_fire(struct fpm_event_s *ev)
Definition fpm_events.c:472
#define NULL
Definition gdcache.h:45
#define POLLIN
struct fpm_event_module_s * fpm_event_port_module(void)
Definition port.c:50
#define close(a)
#define errno
zval * ret
@ ZLOG_ERROR
Definition zlog.h:45
@ ZLOG_WARNING
Definition zlog.h:44
#define zlog(flags,...)
Definition zlog.h:9