diff options
Diffstat (limited to 'src/vnet/session')
-rw-r--r-- | src/vnet/session/session.c | 14 | ||||
-rw-r--r-- | src/vnet/session/stream_session.h | 1 |
2 files changed, 14 insertions, 1 deletions
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c index b48459d5081..069818ef1be 100644 --- a/src/vnet/session/session.c +++ b/src/vnet/session/session.c @@ -819,6 +819,7 @@ stream_session_delete_notify (transport_connection_t * tc) break; case SESSION_STATE_CLOSED: case SESSION_STATE_ACCEPTING: + case SESSION_STATE_CLOSED_WAITING: stream_session_delete (s); break; default: @@ -1112,7 +1113,18 @@ stream_session_disconnect_transport (stream_session_t * s) session_free_w_fifos (s); return; } - s->session_state = SESSION_STATE_CLOSED; + + /* If tx queue wasn't drained, change state to closed waiting for transport. + * This way, the transport, if it so wishes, can continue to try sending the + * outstanding data (in closed state it cannot). It MUST however at one + * point, either after sending everything or after a timeout, call delete + * notify. This will finally lead to the complete cleanup of the session. + */ + if (svm_fifo_max_dequeue (s->server_tx_fifo)) + s->session_state = SESSION_STATE_CLOSED_WAITING; + else + s->session_state = SESSION_STATE_CLOSED; + tp_vfts[session_get_transport_proto (s)].close (s->connection_index, s->thread_index); } diff --git a/src/vnet/session/stream_session.h b/src/vnet/session/stream_session.h index c335c5b833e..79a6839ad21 100644 --- a/src/vnet/session/stream_session.h +++ b/src/vnet/session/stream_session.h @@ -33,6 +33,7 @@ typedef enum SESSION_STATE_OPENED, SESSION_STATE_TRANSPORT_CLOSING, SESSION_STATE_CLOSING, + SESSION_STATE_CLOSED_WAITING, SESSION_STATE_CLOSED, SESSION_STATE_N_STATES, } stream_session_state_t; |