+ svm_msg_q_msg_t _msg, *msg = &_msg;
+ session_migrated_msg_t m = { 0 };
+ fifo_segment_t *eq_seg;
+ app_worker_t *app_wrk;
+ session_event_t *evt;
+ svm_msg_q_t *app_mq;
+ application_t *app;
+ u32 thread_index;
+
+ thread_index = session_thread_from_handle (new_sh);
+ app_wrk = app_worker_get (s->app_wrk_index);
+ app_mq = app_wrk->event_queue;
+ app = application_get (app_wrk->app_index);
+ eq_seg = application_get_rx_mqs_segment (app);
+
+ m.handle = session_handle (s);
+ m.new_handle = new_sh;
+ m.vpp_thread_index = thread_index;
+ m.vpp_evt_q = fifo_segment_msg_q_offset (eq_seg, thread_index);
+ m.segment_handle = SESSION_INVALID_HANDLE;
+
+ if (mq_try_lock_and_alloc_msg (app_mq, msg))
+ return;
+
+ evt = svm_msg_q_msg_data (app_mq, msg);
+ clib_memset (evt, 0, sizeof (*evt));
+ evt->event_type = SESSION_CTRL_EVT_MIGRATED;
+ clib_memcpy_fast (evt->data, &m, sizeof (m));
+
+ svm_msg_q_add_and_unlock (app_mq, msg);
+}
+
+static int
+mq_send_add_segment_cb (u32 app_wrk_index, u64 segment_handle)
+{
+ int fds[SESSION_N_FD_TYPE], n_fds = 0;
+ svm_msg_q_msg_t _msg, *msg = &_msg;
+ session_app_add_segment_msg_t *mp;
+ vl_api_registration_t *reg;
+ app_worker_t *app_wrk;
+ session_event_t *evt;
+ svm_msg_q_t *app_mq;
+ fifo_segment_t *fs;
+ ssvm_private_t *sp;
+ u8 fd_flags = 0;
+
+ app_wrk = app_worker_get (app_wrk_index);
+
+ reg = vl_mem_api_client_index_to_registration (app_wrk->api_client_index);
+ if (!reg)
+ {
+ clib_warning ("no api registration for client: %u",
+ app_wrk->api_client_index);
+ return -1;
+ }
+
+ fs = segment_manager_get_segment_w_handle (segment_handle);
+ sp = &fs->ssvm;
+ if (ssvm_type (sp) == SSVM_SEGMENT_MEMFD)
+ {
+ if (vl_api_registration_file_index (reg) == VL_API_INVALID_FI)
+ {
+ clib_warning ("can't send memfd fd");
+ return -1;
+ }
+
+ fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
+ fds[n_fds] = sp->fd;
+ n_fds += 1;
+ }
+
+ app_mq = app_wrk->event_queue;
+ if (mq_try_lock_and_alloc_msg (app_mq, msg))
+ return -1;
+
+ if (n_fds)
+ session_send_fds (reg, fds, n_fds);
+
+ evt = svm_msg_q_msg_data (app_mq, msg);
+ clib_memset (evt, 0, sizeof (*evt));
+ evt->event_type = SESSION_CTRL_EVT_APP_ADD_SEGMENT;
+ mp = (session_app_add_segment_msg_t *) evt->data;
+ clib_memset (mp, 0, sizeof (*mp));
+ mp->segment_size = sp->ssvm_size;
+ mp->fd_flags = fd_flags;
+ mp->segment_handle = segment_handle;
+ strncpy ((char *) mp->segment_name, (char *) sp->name,
+ sizeof (mp->segment_name) - 1);
+
+ svm_msg_q_add_and_unlock (app_mq, msg);
+
+ return 0;
+}
+
+static int
+mq_send_del_segment_cb (u32 app_wrk_index, u64 segment_handle)
+{
+ svm_msg_q_msg_t _msg, *msg = &_msg;
+ session_app_del_segment_msg_t *mp;
+ vl_api_registration_t *reg;
+ app_worker_t *app_wrk;
+ session_event_t *evt;
+ svm_msg_q_t *app_mq;
+
+ app_wrk = app_worker_get (app_wrk_index);
+ reg = vl_mem_api_client_index_to_registration (app_wrk->api_client_index);
+ if (!reg)
+ {
+ clib_warning ("no registration: %u", app_wrk->api_client_index);
+ return -1;
+ }
+
+ app_mq = app_wrk->event_queue;
+ if (mq_try_lock_and_alloc_msg (app_mq, msg))
+ return -1;
+
+ evt = svm_msg_q_msg_data (app_mq, msg);
+ clib_memset (evt, 0, sizeof (*evt));
+ evt->event_type = SESSION_CTRL_EVT_APP_DEL_SEGMENT;
+ mp = (session_app_del_segment_msg_t *) evt->data;
+ clib_memset (mp, 0, sizeof (*mp));
+ mp->segment_handle = segment_handle;
+ svm_msg_q_add_and_unlock (app_mq, msg);
+
+ return 0;
+}
+
+static void
+mq_send_session_cleanup_cb (session_t * s, session_cleanup_ntf_t ntf)
+{
+ svm_msg_q_msg_t _msg, *msg = &_msg;
+ session_cleanup_msg_t *mp;
+ svm_msg_q_t *app_mq;
+ session_event_t *evt;
+ app_worker_t *app_wrk;
+
+ /* Propagate transport cleanup notifications only if app didn't close */
+ if (ntf == SESSION_CLEANUP_TRANSPORT
+ && s->session_state != SESSION_STATE_TRANSPORT_DELETED)
+ return;
+
+ app_wrk = app_worker_get_if_valid (s->app_wrk_index);
+ if (!app_wrk)
+ return;
+
+ app_mq = app_wrk->event_queue;
+ if (mq_try_lock_and_alloc_msg (app_mq, msg))
+ return;
+
+ evt = svm_msg_q_msg_data (app_mq, msg);
+ clib_memset (evt, 0, sizeof (*evt));
+ evt->event_type = SESSION_CTRL_EVT_CLEANUP;
+ mp = (session_cleanup_msg_t *) evt->data;
+ mp->handle = session_handle (s);
+ mp->type = ntf;
+ svm_msg_q_add_and_unlock (app_mq, msg);