error = clib_file_write (cf);
unix_save_error (&unix_main, error);
- /* Make sure cf not removed in clib_file_write */
- cf = vl_api_registration_file (rp);
- if (!cf)
- {
- clib_warning ("cf removed");
- vl_msg_api_free ((void *) elem);
- return;
- }
-
/* If we didn't finish sending everything, wait for tx space */
if (vec_len (sock_rp->output_vector) > 0
&& !(cf->flags & UNIX_FILE_DATA_AVAILABLE_TO_WRITE))
socket_main.current_rp = 0;
}
+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.
*
clib_error_t *
vl_socket_read_ready (clib_file_t * uf)
{
- clib_file_main_t *fm = &file_main;
vlib_main_t *vm = vlib_get_main ();
vl_api_registration_t *rp;
/* n is the size of data read to input_buffer */
u32 save_input_buffer_length = vec_len (socket_main.input_buffer);
vl_socket_args_for_process_t *a;
u32 reg_index = uf->private_data;
+ if (is_being_removed_reg_index (reg_index))
+ {
+ return 0;
+ }
rp = vl_socket_get_registration (reg_index);
if (errno != EAGAIN)
{
/* Severe error, close the file. */
- clib_file_del (fm, uf);
- vl_socket_free_registration_index (reg_index);
+ vl_socket_request_remove_reg_index (reg_index);
}
/* EAGAIN means we do not close the file, but no data to process anyway. */
return 0;
}
/* Fake smaller length teporarily, so input_buffer can be used as msg_buffer. */
- _vec_len (socket_main.input_buffer) = n;
+ vec_set_len (socket_main.input_buffer, n);
/*
* Look for bugs here. This code is tricky because
vec_validate (rp->unprocessed_input, vec_len (msg_buffer) - 1);
clib_memcpy_fast (rp->unprocessed_input, msg_buffer,
vec_len (msg_buffer));
- _vec_len (rp->unprocessed_input) = vec_len (msg_buffer);
+ vec_set_len (rp->unprocessed_input, vec_len (msg_buffer));
}
/* No more full messages, restore original input_buffer length. */
- _vec_len (socket_main.input_buffer) = save_input_buffer_length;
+ vec_set_len (socket_main.input_buffer, save_input_buffer_length);
return 0;
}
* so we can overwrite its length to what single message has.
*/
data_for_process = (u8 *) vec_dup (msg_buffer);
- _vec_len (data_for_process) = msgbuf_len;
+ vec_set_len (data_for_process, msgbuf_len);
/* Everything is ready to signal the SOCKET_READ_EVENT. */
pool_get (socket_main.process_args, a);
a->reg_index = reg_index;
vec_delete (msg_buffer, msgbuf_len, 0);
else
/* We are done with msg_buffer. */
- _vec_len (msg_buffer) = 0;
+ vec_set_len (msg_buffer, 0);
}
while (vec_len (msg_buffer) > 0);
/* Restore input_buffer, it could have been msg_buffer. */
- _vec_len (socket_main.input_buffer) = save_input_buffer_length;
+ vec_set_len (socket_main.input_buffer, save_input_buffer_length);
return 0;
}
vl_api_registration_t *rp;
int n;
- rp = pool_elt_at_index (socket_main.registration_pool, uf->private_data);
+ u32 reg_index = uf->private_data;
+ if (is_being_removed_reg_index (reg_index))
+ {
+ return 0;
+ }
+
+ rp = pool_elt_at_index (socket_main.registration_pool, reg_index);
/* Flush output vector. */
size_t total_bytes = vec_len (rp->output_vector);
#if DEBUG > 2
clib_warning ("write error, close the file...\n");
#endif
- clib_file_del (fm, uf);
- vl_socket_free_registration_index (rp -
- socket_main.registration_pool);
+ vl_socket_request_remove_reg_index (reg_index);
return 0;
}
remaining_bytes -= bytes_to_send;
clib_error_t *
vl_socket_error_ready (clib_file_t * uf)
{
- vl_api_registration_t *rp;
- clib_file_main_t *fm = &file_main;
-
- rp = pool_elt_at_index (socket_main.registration_pool, uf->private_data);
- clib_file_del (fm, uf);
- vl_socket_free_registration_index (rp - socket_main.registration_pool);
-
+ u32 reg_index = uf->private_data;
+ vl_socket_request_remove_reg_index (reg_index);
return 0;
}
regp = socket_main.current_rp;
- ASSERT (regp->registration_type == REGISTRATION_TYPE_SOCKET_SERVER);
+ /* client already connected through shared memory? */
+ if (!regp || regp->registration_type != REGISTRATION_TYPE_SOCKET_SERVER)
+ {
+ clib_warning (
+ "unsupported API call: already connected though shared memory?");
+ return;
+ }
regp->name = format (0, "%s%c", mp->name, 0);
vl_sock_api_send_fd_msg (cf->file_descriptor, &memfd->fd, 1);
}
-#define foreach_vlib_api_msg \
- _(SOCKCLNT_CREATE, sockclnt_create, 1) \
- _(SOCKCLNT_DELETE, sockclnt_delete, 1) \
- _(SOCK_INIT_SHM, sock_init_shm, 1)
+#define foreach_vlib_api_msg \
+ _ (SOCKCLNT_CREATE, sockclnt_create, 0) \
+ _ (SOCKCLNT_DELETE, sockclnt_delete, 0) \
+ _ (SOCK_INIT_SHM, sock_init_shm, 0)
clib_error_t *
vl_sock_api_init (vlib_main_t * vm)
{
+ api_main_t *am = vlibapi_get_main ();
clib_file_main_t *fm = &file_main;
clib_file_t template = { 0 };
vl_api_registration_t *rp;
if (sm->socket_name == 0)
return 0;
-#define _(N,n,t) \
- vl_msg_api_set_handlers(VL_API_##N, #n, \
- vl_api_##n##_t_handler, \
- vl_noop_handler, \
- vl_api_##n##_t_endian, \
- vl_api_##n##_t_print, \
- sizeof(vl_api_##n##_t), t);
+#define _(N, n, t) \
+ vl_msg_api_set_handlers (VL_API_##N, #n, vl_api_##n##_t_handler, \
+ vl_noop_handler, vl_api_##n##_t_endian, \
+ vl_api_##n##_t_print, sizeof (vl_api_##n##_t), t, \
+ vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \
+ vl_api_##n##_t_fromjson); \
+ am->api_trace_cfg[VL_API_##N].replay_enable = 0;
foreach_vlib_api_msg;
#undef _