+int
+is_being_removed_reg_index (u32 reg_index)
+{
+ vl_api_registration_t *rp = vl_socket_get_registration (reg_index);
+ ALWAYS_ASSERT (rp != 0);
+ return (rp->is_being_removed);
+}
+
+static void
+socket_cleanup_pending_remove_registration_cb (u32 *preg_index)
+{
+ vl_api_registration_t *rp = vl_socket_get_registration (*preg_index);
+ clib_file_main_t *fm = &file_main;
+ u32 pending_remove_file_index = vl_api_registration_file_index (rp);
+
+ clib_file_t *zf = fm->file_pool + pending_remove_file_index;
+
+ clib_file_del (fm, zf);
+ vl_socket_free_registration_index (rp - socket_main.registration_pool);
+}
+
+static void
+vl_socket_request_remove_reg_index (u32 reg_index)
+{
+ vl_api_registration_t *rp = vl_socket_get_registration (reg_index);
+ ALWAYS_ASSERT (rp != 0);
+ if (rp->is_being_removed)
+ {
+ return;
+ }
+ rp->is_being_removed = 1;
+ vl_api_force_rpc_call_main_thread (
+ socket_cleanup_pending_remove_registration_cb, (void *) ®_index,
+ sizeof (u32));
+}
+
+/*
+ * Read function for API socket.
+ *
+ * Read data from socket, invoke SOCKET_READ_EVENT
+ * for each fully read API message, return 0.
+ * Store incomplete data for next invocation to continue.
+ *
+ * On severe read error, the file is closed.
+ *
+ * As reading is single threaded,
+ * socket_main.input_buffer is used temporarily.
+ * Even its length is modified, but always restored before return.
+ *
+ * Incomplete data is copied into a vector,
+ * pointer saved in registration's unprocessed_input.
+ */