From d3e853514f86cfaa1555415a99e52f72785feccc Mon Sep 17 00:00:00 2001 From: Gavin Lambert Date: Wed, 1 Jun 2016 09:55:24 +0200 Subject: [PATCH] Applied base-0027-Prevent abandoning the mailbox state machines early Fixup for f943348d - caused deadlock. Fixes the exit condition of the mailbox FSMs -- previously they returned whether they were sending a datagram or not, and the parent assumed that this meant they were done if they didn't want to send a datagram. Since earlier patches can cause idle cycles now, this could cause unexpected early exit, so they now return whether they're complete or not explicitly. --- master/fsm_coe.c | 21 ++++++++++----------- master/fsm_eoe.c | 20 ++++++++++---------- master/fsm_foe.c | 20 ++++++++++---------- master/fsm_soe.c | 20 ++++++++++---------- 4 files changed, 40 insertions(+), 41 deletions(-) diff --git a/master/fsm_coe.c b/master/fsm_coe.c index 1d3f4719..f9620c34 100644 --- a/master/fsm_coe.c +++ b/master/fsm_coe.c @@ -230,35 +230,34 @@ void ec_fsm_coe_transfer( /** Executes the current state of the state machine. * - * \return 1 if the datagram was used, else 0. + * \return 1 if the state machine is still in progress, else 0. */ int ec_fsm_coe_exec( ec_fsm_coe_t *fsm, /**< Finite state machine. */ ec_datagram_t *datagram /**< Datagram to use. */ ) { - int datagram_used = 0; - + if (fsm->state == ec_fsm_coe_end || fsm->state == ec_fsm_coe_error) + return 0; if (fsm->datagram && (fsm->datagram->state == EC_DATAGRAM_INIT || fsm->datagram->state == EC_DATAGRAM_QUEUED || fsm->datagram->state == EC_DATAGRAM_SENT)) { // datagram not received yet - return datagram_used; + if (datagram != fsm->datagram) + datagram->state = EC_DATAGRAM_INVALID; + return 1; } fsm->state(fsm, datagram); - datagram_used = - fsm->state != ec_fsm_coe_end && fsm->state != ec_fsm_coe_error; - - if (datagram_used) { - fsm->datagram = datagram; - } else { + if (fsm->state == ec_fsm_coe_end || fsm->state == ec_fsm_coe_error) { fsm->datagram = NULL; + return 0; } - return datagram_used; + fsm->datagram = datagram; + return 1; } /*****************************************************************************/ diff --git a/master/fsm_eoe.c b/master/fsm_eoe.c index d1f3dc23..a4a37ec1 100644 --- a/master/fsm_eoe.c +++ b/master/fsm_eoe.c @@ -101,35 +101,35 @@ void ec_fsm_eoe_set_ip_param( /** Executes the current state of the state machine. * - * \return 1 if the datagram was used, else 0. + * \return 1 if the state machine is still in progress, else 0. */ int ec_fsm_eoe_exec( ec_fsm_eoe_t *fsm, /**< finite state machine */ ec_datagram_t *datagram /**< Datagram to use. */ ) { - int datagram_used = 0; + if (fsm->state == ec_fsm_eoe_end || fsm->state == ec_fsm_eoe_error) + return 0; if (fsm->datagram && (fsm->datagram->state == EC_DATAGRAM_INIT || fsm->datagram->state == EC_DATAGRAM_QUEUED || fsm->datagram->state == EC_DATAGRAM_SENT)) { // datagram not received yet - return datagram_used; + if (datagram != fsm->datagram) + datagram->state = EC_DATAGRAM_INVALID; + return 1; } fsm->state(fsm, datagram); - datagram_used = - fsm->state != ec_fsm_eoe_end && fsm->state != ec_fsm_eoe_error; - - if (datagram_used) { - fsm->datagram = datagram; - } else { + if (fsm->state == ec_fsm_eoe_end || fsm->state == ec_fsm_eoe_error) { fsm->datagram = NULL; + return 0; } - return datagram_used; + fsm->datagram = datagram; + return 1; } /*****************************************************************************/ diff --git a/master/fsm_foe.c b/master/fsm_foe.c index debd17c9..1ce7b7aa 100644 --- a/master/fsm_foe.c +++ b/master/fsm_foe.c @@ -123,35 +123,35 @@ void ec_fsm_foe_clear(ec_fsm_foe_t *fsm /**< finite state machine */) /** Executes the current state of the state machine. * - * \return 1, if the datagram was used, else 0. + * \return 1 if the state machine is still in progress, else 0. */ int ec_fsm_foe_exec( ec_fsm_foe_t *fsm, /**< finite state machine */ ec_datagram_t *datagram /**< Datagram to use. */ ) { - int datagram_used = 0; + if (fsm->state == ec_fsm_foe_end || fsm->state == ec_fsm_foe_error) + return 0; if (fsm->datagram && (fsm->datagram->state == EC_DATAGRAM_INIT || fsm->datagram->state == EC_DATAGRAM_QUEUED || fsm->datagram->state == EC_DATAGRAM_SENT)) { // datagram not received yet - return datagram_used; + if (datagram != fsm->datagram) + datagram->state = EC_DATAGRAM_INVALID; + return 1; } fsm->state(fsm, datagram); - datagram_used = - fsm->state != ec_fsm_foe_end && fsm->state != ec_fsm_foe_error; - - if (datagram_used) { - fsm->datagram = datagram; - } else { + if (fsm->state == ec_fsm_foe_end || fsm->state == ec_fsm_foe_error) { fsm->datagram = NULL; + return 0; } - return datagram_used; + fsm->datagram = datagram; + return 1; } /*****************************************************************************/ diff --git a/master/fsm_soe.c b/master/fsm_soe.c index e7cbadff..cd904a72 100644 --- a/master/fsm_soe.c +++ b/master/fsm_soe.c @@ -147,35 +147,35 @@ void ec_fsm_soe_transfer( /** Executes the current state of the state machine. * - * \return 1 if the datagram was used, else 0. + * \return 1 if the state machine is still in progress, else 0. */ int ec_fsm_soe_exec( ec_fsm_soe_t *fsm, /**< finite state machine */ ec_datagram_t *datagram /**< Datagram to use. */ ) { - int datagram_used = 0; + if (fsm->state == ec_fsm_soe_end || fsm->state == ec_fsm_soe_error) + return 0; if (fsm->datagram && (fsm->datagram->state == EC_DATAGRAM_INIT || fsm->datagram->state == EC_DATAGRAM_QUEUED || fsm->datagram->state == EC_DATAGRAM_SENT)) { // datagram not received yet - return datagram_used; + if (datagram != fsm->datagram) + datagram->state = EC_DATAGRAM_INVALID; + return 1; } fsm->state(fsm, datagram); - datagram_used = - fsm->state != ec_fsm_soe_end && fsm->state != ec_fsm_soe_error; - - if (datagram_used) { - fsm->datagram = datagram; - } else { + if (fsm->state == ec_fsm_soe_end || fsm->state == ec_fsm_soe_error) { fsm->datagram = NULL; + return 0; } - return datagram_used; + fsm->datagram = datagram; + return 1; } /*****************************************************************************/