+ while (1)
+ {
+ if (vec_len (cm->new_sessions) > 0)
+ wait = vlib_process_wait_for_event_or_clock (vm, wait);
+ else
+ vlib_process_wait_for_event (vm);
+
+ event_type = vlib_process_get_events (vm, &event_data);
+
+ switch (event_type)
+ {
+ case ~0: /* no events => timeout */
+ break;
+
+ case UNIX_CLI_NEW_SESSION_EVENT_ADD:
+ {
+ /* Add an identifier to the new session list */
+ unix_cli_new_session_t ns;
+
+ ns.cf_index = event_data[0];
+ ns.deadline = vlib_time_now (vm) + 1.0;
+
+ vec_add1 (cm->new_sessions, ns);
+
+ if (wait > 0.1)
+ wait = 0.1; /* force a re-evaluation soon, but not too soon */
+ }
+ break;
+
+ default:
+ clib_warning ("BUG: unknown event type 0x%wx", event_type);
+ break;
+ }
+
+ vec_reset_length (event_data);
+
+ if (vlib_process_suspend_time_is_zero (wait))
+ {
+ /* Scan the list looking for expired deadlines.
+ * Emit needed prompts and remove from the list.
+ * While scanning, look for the nearest new deadline
+ * for the next iteration.
+ * Since the list is ordered with newest sessions first
+ * we can make assumptions about expired sessions being
+ * contiguous at the beginning and the next deadline is the
+ * next entry on the list, if any.
+ */
+ f64 now = vlib_time_now (vm);
+ unix_cli_new_session_t *nsp;
+ word index = 0;
+
+ wait = INFINITY;
+
+ vec_foreach (nsp, cm->new_sessions)
+ {
+ if (vlib_process_suspend_time_is_zero (nsp->deadline - now))
+ {
+ /* Deadline reached */
+ unix_cli_file_t *cf;
+
+ /* Mark the highwater */
+ index++;
+
+ /* Check the connection didn't close already */
+ if (pool_is_free_index (cm->cli_file_pool, nsp->cf_index))
+ continue;
+
+ cf = pool_elt_at_index (cm->cli_file_pool, nsp->cf_index);
+
+ if (!cf->started)
+ unix_cli_file_welcome (cm, cf);
+ }
+ else
+ {
+ wait = nsp->deadline - now;
+ break;
+ }
+ }