If the shutdown gets delayed until the state transition from
STATE_RESET_CONNECTING completes and the reconnect is successful
(i.e. next_state is STATE_READY), we eventually hit "unexpected
state transition" assert in advance_state(). The reason is that
advance_state() would update m_state and call disconnect() under
STATE_READY instead of STATE_SHUTTING_DOWN. After the disconnect
maybe_finalize_shutdown() would enter advance_state() again with
STATE_SHUTDOWN as next_state, but the transition to that from
STATE_READY is invalid.
Plug this by not transitioning to next_state if current_state is
STATE_SHUTTING_DOWN.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
m_on_shutdown = on_finish;
auto current_state = m_state;
+ m_state = STATE_SHUTTING_DOWN;
+
if (current_state == STATE_UNINITIALIZED) {
// never initialized or resolve/connect failed
on_finish->complete(0);
return;
- }
-
- m_state = STATE_SHUTTING_DOWN;
- if (current_state != STATE_READY) {
+ } else if (current_state != STATE_READY) {
// delay shutdown until current state transition completes
return;
}
<< "next_state=" << next_state << ", "
<< "r=" << r << dendl;
- m_state = next_state;
+ if (current_state != STATE_SHUTTING_DOWN) {
+ m_state = next_state;
+ }
+
if (current_state == STATE_CONNECTING) {
if (next_state == STATE_UNINITIALIZED) {
shutdown_socket();