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.
This commit is contained in:
Gavin Lambert 2016-06-01 09:55:24 +02:00 committed by Knud Baastrup
parent ff2e062a08
commit d3e853514f
4 changed files with 40 additions and 41 deletions

View File

@ -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;
}
/*****************************************************************************/

View File

@ -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;
}
/*****************************************************************************/

View File

@ -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;
}
/*****************************************************************************/

View File

@ -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;
}
/*****************************************************************************/