memset (app, 0, sizeof (*app));
app->index = application_get_index (app);
app->connects_seg_manager = ~0;
+ app->first_segment_manager = ~0;
+ if (CLIB_DEBUG > 1)
+ clib_warning ("[%d] New app (%d)", getpid (), app->index);
return app;
}
void
application_del (application_t * app)
{
- api_main_t *am = &api_main;
- void *oldheap;
segment_manager_t *sm;
u64 handle;
u32 index, *handles = 0;
int i;
vnet_unbind_args_t _a, *a = &_a;
+ /*
+ * The app event queue allocated in first segment is cleared with
+ * the segment manager. No need to explicitly free it.
+ */
+ if (CLIB_DEBUG > 1)
+ clib_warning ("[%d] Delete app (%d)", getpid (), app->index);
+
/*
* Cleanup segment managers
*/
- if (app->connects_seg_manager != (u32) ~ 0)
+ if ((app->connects_seg_manager != (u32) ~ 0) &&
+ (app->connects_seg_manager != app->first_segment_manager))
{
sm = segment_manager_get (app->connects_seg_manager);
segment_manager_del (sm);
/* Actual listener cleanup */
for (i = 0; i < vec_len (handles); i++)
{
- a->app_index = app->api_client_index;
+ a->app_index = app->index;
a->handle = handles[i];
/* seg manager is removed when unbind completes */
vnet_unbind (a);
}
- /*
- * Free the event fifo in the /vpe-api shared-memory segment
- */
- oldheap = svm_push_data_heap (am->vlib_rp);
- if (app->event_queue)
- unix_shared_memory_queue_free (app->event_queue);
- svm_pop_heap (oldheap);
+ if (app->first_segment_manager != ~0)
+ {
+ sm = segment_manager_get (app->first_segment_manager);
+ segment_manager_first_segment_maybe_del (sm);
+ }
application_table_del (app);
pool_put (app_pool, app);
application_init (application_t * app, u32 api_client_index, u64 * options,
session_cb_vft_t * cb_fns)
{
- api_main_t *am = &api_main;
segment_manager_t *sm;
segment_manager_properties_t *props;
- void *oldheap;
- u32 app_evt_queue_size;
+ u32 app_evt_queue_size, first_seg_size;
int rv;
app_evt_queue_size = options[APP_EVT_QUEUE_SIZE] > 0 ?
options[APP_EVT_QUEUE_SIZE] : default_app_evt_queue_size;
- /* Allocate event fifo in the /vpe-api shared-memory segment */
- oldheap = svm_push_data_heap (am->vlib_rp);
-
- /* Allocate server event queue */
- app->event_queue =
- unix_shared_memory_queue_init (app_evt_queue_size,
- sizeof (session_fifo_event_t),
- 0 /* consumer pid */ ,
- 0
- /* (do not) signal when queue non-empty */
- );
-
- svm_pop_heap (oldheap);
-
/* Setup segment manager */
sm = segment_manager_new ();
sm->app_index = app->index;
props->rx_fifo_size = options[SESSION_OPTIONS_RX_FIFO_SIZE];
props->tx_fifo_size = options[SESSION_OPTIONS_TX_FIFO_SIZE];
props->add_segment = props->add_segment_size != 0;
-
- if ((rv = segment_manager_init (sm, props,
- options[SESSION_OPTIONS_SEGMENT_SIZE])))
+ props->preallocated_fifo_pairs = options[APP_OPTIONS_PREALLOC_FIFO_PAIRS];
+ props->use_private_segment = options[APP_OPTIONS_FLAGS]
+ & APP_OPTIONS_FLAGS_BUILTIN_APP;
+ props->private_segment_count = options[APP_OPTIONS_PRIVATE_SEGMENT_COUNT];
+ props->private_segment_size = options[APP_OPTIONS_PRIVATE_SEGMENT_SIZE];
+
+ first_seg_size = options[SESSION_OPTIONS_SEGMENT_SIZE];
+ if ((rv = segment_manager_init (sm, props, first_seg_size)))
return rv;
app->first_segment_manager = segment_manager_index (sm);
app->api_client_index = api_client_index;
- app->flags = options[SESSION_OPTIONS_FLAGS];
+ app->flags = options[APP_OPTIONS_FLAGS];
app->cb_fns = *cb_fns;
+ /* Allocate app event queue in the first shared-memory segment */
+ app->event_queue = segment_manager_alloc_queue (sm, app_evt_queue_size);
+
/* Check that the obvious things are properly set up */
application_verify_cb_fns (cb_fns);
{
segment_manager_t *sm = 0;
- if (app->first_segment_manager != (u32) ~ 0)
+ if (app->first_segment_manager != (u32) ~ 0
+ && app->first_segment_manager_in_use == 0)
{
sm = segment_manager_get (app->first_segment_manager);
- app->first_segment_manager = ~0;
+ app->first_segment_manager_in_use = 1;
return sm;
}
sm = segment_manager_new ();
- if (segment_manager_init (sm, &app->sm_properties, 0))
- return 0;
+ sm->properties = &app->sm_properties;
+
return sm;
}
sm = segment_manager_get (*indexp);
segment_manager_del (sm);
+ if (srv->first_segment_manager == *indexp)
+ {
+ srv->first_segment_manager_in_use = 0;
+ srv->first_segment_manager = ~0;
+ }
hash_unset (srv->listeners_table, handle);
listen_session_del (listener);
return rv;
/* Store api_context for when the reply comes. Not the nicest thing
- * but better allocating a separate half-open pool. */
+ * but better than allocating a separate half-open pool. */
tc->s_index = api_context;
return 0;
return app_name;
}
+int
+application_is_proxy (application_t * app)
+{
+ return !(app->flags & APP_OPTIONS_FLAGS_IS_PROXY);
+}
+
u8 *
format_application_listener (u8 * s, va_list * args)
{
vlib_main_t *vm = vlib_get_main ();
segment_manager_t *sm;
u8 *app_name, *s = 0;
- int i, j;
+ int j;
/* Header */
if (app == 0)
for (j = 0; j < vec_len (sm->segment_indices); j++)
{
svm_fifo_segment_private_t *fifo_segment;
- svm_fifo_t **fifos;
+ svm_fifo_t *fifo;
u8 *str;
fifo_segment = svm_fifo_get_segment (sm->segment_indices[j]);
- fifos = svm_fifo_segment_get_fifos (fifo_segment);
- for (i = 0; i < vec_len (fifos); i++)
+ fifo = svm_fifo_segment_get_fifo_list (fifo_segment);
+ while (fifo)
{
- svm_fifo_t *fifo;
u32 session_index, thread_index;
stream_session_t *session;
- /* There are 2 fifos/session. Avoid printing twice. */
- if (i % 2)
- continue;
-
- fifo = fifos[i];
- session_index = fifo->server_session_index;
- thread_index = fifo->server_thread_index;
+ session_index = fifo->master_session_index;
+ thread_index = fifo->master_thread_index;
session = stream_session_get (session_index, thread_index);
str = format (0, "%U", format_stream_session, session, verbose);
s = format (s, "%-40s%-20s", str, app_name);
vlib_cli_output (vm, "%v", s);
-
vec_reset_length (s);
vec_free (str);
+
+ fifo = fifo->next;
}
vec_free (s);
}