Stop handling file descriptor events after a port reset.
If the port resets itself after detecting a fault, then the polling events for that port are no longer valid. This patch fixes a latent bug that would appear if a fault and another event were to happen simultaneously. Signed-off-by: Richard Cochran <richardcochran@gmail.com>master
parent
da594e78d9
commit
0dbdd9c2cd
6
clock.c
6
clock.c
|
@ -692,7 +692,7 @@ struct PortIdentity clock_parent_identity(struct clock *c)
|
||||||
|
|
||||||
int clock_poll(struct clock *c)
|
int clock_poll(struct clock *c)
|
||||||
{
|
{
|
||||||
int cnt, i, j, k, lost = 0, sde = 0;
|
int cnt, err, i, j, k, lost = 0, sde = 0;
|
||||||
enum fsm_event event;
|
enum fsm_event event;
|
||||||
|
|
||||||
cnt = poll(c->pollfd, ARRAY_SIZE(c->pollfd), -1);
|
cnt = poll(c->pollfd, ARRAY_SIZE(c->pollfd), -1);
|
||||||
|
@ -710,7 +710,7 @@ int clock_poll(struct clock *c)
|
||||||
for (i = 0; i < c->nports; i++) {
|
for (i = 0; i < c->nports; i++) {
|
||||||
|
|
||||||
/* Let the ports handle their events. */
|
/* Let the ports handle their events. */
|
||||||
for (j = 0; j < N_POLLFD; j++) {
|
for (j = err = 0; j < N_POLLFD && !err; j++) {
|
||||||
k = N_CLOCK_PFD * i + j;
|
k = N_CLOCK_PFD * i + j;
|
||||||
if (c->pollfd[k].revents & (POLLIN|POLLPRI)) {
|
if (c->pollfd[k].revents & (POLLIN|POLLPRI)) {
|
||||||
event = port_event(c->port[i], j);
|
event = port_event(c->port[i], j);
|
||||||
|
@ -718,7 +718,7 @@ int clock_poll(struct clock *c)
|
||||||
sde = 1;
|
sde = 1;
|
||||||
if (EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES == event)
|
if (EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES == event)
|
||||||
lost = 1;
|
lost = 1;
|
||||||
port_dispatch(c->port[i], event, 0);
|
err = port_dispatch(c->port[i], event, 0);
|
||||||
/* Clear any fault after a little while. */
|
/* Clear any fault after a little while. */
|
||||||
if (PS_FAULTY == port_state(c->port[i])) {
|
if (PS_FAULTY == port_state(c->port[i])) {
|
||||||
clock_fault_timeout(c, i, 1);
|
clock_fault_timeout(c, i, 1);
|
||||||
|
|
7
port.c
7
port.c
|
@ -1406,7 +1406,7 @@ struct foreign_clock *port_compute_best(struct port *p)
|
||||||
return p->best;
|
return p->best;
|
||||||
}
|
}
|
||||||
|
|
||||||
void port_dispatch(struct port *p, enum fsm_event event, int mdiff)
|
int port_dispatch(struct port *p, enum fsm_event event, int mdiff)
|
||||||
{
|
{
|
||||||
enum port_state next;
|
enum port_state next;
|
||||||
|
|
||||||
|
@ -1432,11 +1432,11 @@ void port_dispatch(struct port *p, enum fsm_event event, int mdiff)
|
||||||
next = port_initialize(p) ? PS_FAULTY : PS_LISTENING;
|
next = port_initialize(p) ? PS_FAULTY : PS_LISTENING;
|
||||||
port_show_transition(p, next, event);
|
port_show_transition(p, next, event);
|
||||||
p->state = next;
|
p->state = next;
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next == p->state)
|
if (next == p->state)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
port_show_transition(p, next, event);
|
port_show_transition(p, next, event);
|
||||||
|
|
||||||
|
@ -1493,6 +1493,7 @@ void port_dispatch(struct port *p, enum fsm_event event, int mdiff)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
p->state = next;
|
p->state = next;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum fsm_event port_event(struct port *p, int fd_index)
|
enum fsm_event port_event(struct port *p, int fd_index)
|
||||||
|
|
4
port.h
4
port.h
|
@ -68,8 +68,10 @@ struct foreign_clock *port_compute_best(struct port *port);
|
||||||
* @param port A pointer previously obtained via port_open().
|
* @param port A pointer previously obtained via port_open().
|
||||||
* @param event One of the @a fsm_event codes.
|
* @param event One of the @a fsm_event codes.
|
||||||
* @param mdiff Whether a new master has been selected.
|
* @param mdiff Whether a new master has been selected.
|
||||||
|
* @return Zero if the port's file descriptor array is still valid,
|
||||||
|
* and non-zero if it has become invalid.
|
||||||
*/
|
*/
|
||||||
void port_dispatch(struct port *p, enum fsm_event event, int mdiff);
|
int port_dispatch(struct port *p, enum fsm_event event, int mdiff);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates state machine events based on activity on a port's file
|
* Generates state machine events based on activity on a port's file
|
||||||
|
|
Loading…
Reference in New Issue