diff --git a/NEWS b/NEWS index 586097b5b4..482088e0e0 100644 --- a/NEWS +++ b/NEWS @@ -52,6 +52,7 @@ PHP NEWS . Enable process renaming on macOS. (devnexen) . Added pm.max_spawn_rate option to configure max spawn child processes rate. (Paulius Sapragonas) + . Fixed bug #65800 (Events port mechanism). (psumbera) - FTP: . Convert resource to object \FTP\Connection. (Sara) diff --git a/sapi/fpm/fpm/events/port.c b/sapi/fpm/fpm/events/port.c index 95fe75c8ee..bb703a9b21 100644 --- a/sapi/fpm/fpm/events/port.c +++ b/sapi/fpm/fpm/events/port.c @@ -112,7 +112,8 @@ static int fpm_event_port_clean() /* {{{ */ */ static int fpm_event_port_wait(struct fpm_event_queue_s *queue, unsigned long int timeout) /* {{{ */ { - int ret, i, nget; + int ret + unsigned int i, nget; timespec_t t; /* convert timeout into timespec_t */ @@ -121,6 +122,8 @@ static int fpm_event_port_wait(struct fpm_event_queue_s *queue, unsigned long in /* wait for incoming event or timeout. We want at least one event or timeout */ nget = 1; + events[0].portev_user = (void *)-1; /* so we can double check that an event was returned */ + ret = port_getn(pfd, events, nevents, &nget, &t); if (ret < 0) { @@ -128,6 +131,16 @@ static int fpm_event_port_wait(struct fpm_event_queue_s *queue, unsigned long in if (errno != EINTR && errno != ETIME) { zlog(ZLOG_WARNING, "poll() returns %d", errno); return -1; + } else if (nget > 0 && events[0].portev_user == (void *)-1) { + /* This confusing API can return an event at the same time + * that it reports EINTR or ETIME. If that occurs, just + * report the event. With EINTR, nget can be > 0 without + * any event, so check that portev_user was filled in. + * + * See discussion thread + * http://marc.info/?l=opensolaris-networking-discuss&m=125071205204540 + */ + nget = 0; } }