+
+ /* Make sure we don't try to send anything more */
+ svm_fifo_dequeue_drop_all (s->server_tx_fifo);
+
+ switch (s->session_state)
+ {
+ case SESSION_STATE_TRANSPORT_CLOSING:
+ /* If transport finishes or times out before we get a reply
+ * from the app, do the whole disconnect since we might still
+ * have lingering events. Cleanup session table in advance
+ * because transport will soon be closed and closed sessions
+ * are assumed to have been removed from the lookup table */
+ session_lookup_del_session (s);
+ stream_session_disconnect (s);
+ s->session_state = SESSION_STATE_CLOSED;
+ break;
+ case SESSION_STATE_CLOSING:
+ /* Cleanup lookup table. Transport needs to still be valid */
+ session_lookup_del_session (s);
+ s->session_state = SESSION_STATE_CLOSED;
+ break;
+ case SESSION_STATE_CLOSED:
+ case SESSION_STATE_ACCEPTING:
+ case SESSION_STATE_CLOSED_WAITING:
+ stream_session_delete (s);
+ break;
+ default:
+ stream_session_delete (s);
+ break;
+ }
+}
+
+/**
+ * Notification from transport that session can be closed
+ *
+ * Should be called by transport only if it was closed with non-empty
+ * tx fifo and once it decides to begin the closing procedure prior to
+ * issuing a delete notify. This gives the chance to the session layer
+ * to cleanup any outstanding events.
+ */
+void
+session_stream_close_notify (transport_connection_t * tc)
+{
+ stream_session_t *s;
+
+ if (!(s = session_get_if_valid (tc->s_index, tc->thread_index)))
+ return;
+ s->session_state = SESSION_STATE_CLOSED;