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 cnt, i, j, k, lost = 0, sde = 0;
|
||||
int cnt, err, i, j, k, lost = 0, sde = 0;
|
||||
enum fsm_event event;
|
||||
|
||||
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++) {
|
||||
|
||||
/* 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;
|
||||
if (c->pollfd[k].revents & (POLLIN|POLLPRI)) {
|
||||
event = port_event(c->port[i], j);
|
||||
|
@ -718,7 +718,7 @@ int clock_poll(struct clock *c)
|
|||
sde = 1;
|
||||
if (EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES == event)
|
||||
lost = 1;
|
||||
port_dispatch(c->port[i], event, 0);
|
||||
err = port_dispatch(c->port[i], event, 0);
|
||||
/* Clear any fault after a little while. */
|
||||
if (PS_FAULTY == port_state(c->port[i])) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -1432,11 +1432,11 @@ void port_dispatch(struct port *p, enum fsm_event event, int mdiff)
|
|||
next = port_initialize(p) ? PS_FAULTY : PS_LISTENING;
|
||||
port_show_transition(p, next, event);
|
||||
p->state = next;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (next == p->state)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 event One of the @a fsm_event codes.
|
||||
* @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
|
||||
|
|
Loading…
Reference in New Issue