+ int n_written, bytes, total_copy_bytes;
+ int n_read;
+ svm_fifo_t *tx_fifo;
+ builtin_server_main_t *bsm = &builtin_server_main;
+ session_fifo_event_t evt;
+ static int serial_number = 0;
+
+ bytes = e->enqueue_length;
+ if (PREDICT_FALSE (bytes <= 0))
+ {
+ clib_warning ("bizarre rx callback: bytes %d", bytes);
+ return 0;
+ }
+
+ tx_fifo = s->server_tx_fifo;
+
+ /* Number of bytes we're going to copy */
+ total_copy_bytes = (bytes < (tx_fifo->nitems - tx_fifo->cursize)) ? bytes :
+ tx_fifo->nitems - tx_fifo->cursize;
+
+ if (PREDICT_FALSE (total_copy_bytes <= 0))
+ {
+ clib_warning ("no space in tx fifo, event had %d bytes", bytes);
+ return 0;
+ }
+
+ vec_validate (bsm->rx_buf, total_copy_bytes - 1);
+ _vec_len (bsm->rx_buf) = total_copy_bytes;
+
+ n_read = svm_fifo_dequeue_nowait (s->server_rx_fifo, 0, total_copy_bytes,
+ bsm->rx_buf);
+ ASSERT (n_read == total_copy_bytes);
+
+ /*
+ * Echo back
+ */
+
+ n_written = svm_fifo_enqueue_nowait (tx_fifo, 0, n_read, bsm->rx_buf);
+ ASSERT (n_written == total_copy_bytes);
+
+ /* Fabricate TX event, send to vpp */
+ evt.fifo = tx_fifo;
+ evt.event_type = FIFO_EVENT_SERVER_TX;
+ evt.enqueue_length = total_copy_bytes;
+ evt.event_id = serial_number++;
+
+ unix_shared_memory_queue_add (bsm->vpp_queue[s->thread_index], (u8 *) & evt,
+ 0 /* do wait for mutex */ );
+