l3cfg: add assertion for scheduling timeout in _l3_acd_data_timeout_schedule()
The first point is that ACD timeout is strongly tied to the current state. That is (somewhat) obvious, because _l3_acd_data_state_set_full() will clear any pending timeout. So you can only schedule a timeout *after* setting the state, and setting the next state, will clear the timeout. Likewise, note that l3_acd_data_state_change() for the event ACD_STATE_CHANGE_MODE_TIMEOUT asserts that it is only called in the few states where that is expected. See rhbz#2047788 where that assertion gets hit. The first point means that we must only schedule a timer when we are also in a state that supports that. Add an assertion for that at the point when scheduling the timeout. The assert at this point is useful, because it catches the moment when we do the wrong thing (instead of getting the assertion later during the timeout, when we no longer know where the error happened). See-also: https://bugzilla.redhat.com/show_bug.cgi?id=2047788
This commit is contained in:
@@ -1929,6 +1929,19 @@ _l3_acd_data_timeout_cb(gpointer user_data)
|
|||||||
static void
|
static void
|
||||||
_l3_acd_data_timeout_schedule(AcdData *acd_data, gint64 timeout_msec)
|
_l3_acd_data_timeout_schedule(AcdData *acd_data, gint64 timeout_msec)
|
||||||
{
|
{
|
||||||
|
/* in _l3_acd_data_state_set_full() we clear the timer. At the same time,
|
||||||
|
* in _l3_acd_data_state_change(ACD_STATE_CHANGE_MODE_TIMEOUT) we only
|
||||||
|
* expect timeouts in certain states.
|
||||||
|
*
|
||||||
|
* That means, scheduling a timeout is only correct if we are in a certain
|
||||||
|
* state, which allows to handle timeouts. This assert checks for that to
|
||||||
|
* ensure we don't call a timeout in an unexpected state. */
|
||||||
|
nm_assert(NM_IN_SET(acd_data->info.state,
|
||||||
|
NM_L3_ACD_ADDR_STATE_PROBING,
|
||||||
|
NM_L3_ACD_ADDR_STATE_USED,
|
||||||
|
NM_L3_ACD_ADDR_STATE_DEFENDING,
|
||||||
|
NM_L3_ACD_ADDR_STATE_CONFLICT));
|
||||||
|
|
||||||
nm_clear_g_source_inst(&acd_data->acd_data_timeout_source);
|
nm_clear_g_source_inst(&acd_data->acd_data_timeout_source);
|
||||||
acd_data->acd_data_timeout_source =
|
acd_data->acd_data_timeout_source =
|
||||||
nm_g_timeout_add_source(NM_CLAMP((gint64) 0, timeout_msec, (gint64) G_MAXUINT),
|
nm_g_timeout_add_source(NM_CLAMP((gint64) 0, timeout_msec, (gint64) G_MAXUINT),
|
||||||
|
Reference in New Issue
Block a user