- /* $$$ pay attention to frame size, control CPU usage */
- while (1)
- {
- /*
- * There's a reason for checking the queue before
- * sleeping. If the vlib application crashes, it's entirely
- * possible for a client to enqueue a connect request
- * during the process restart interval.
- *
- * Unless some force of physics causes the new incarnation
- * of the application to process the request, the client will
- * sit and wait for Godot...
- */
- vector_rate = (f64) vlib_last_vectors_per_main_loop (vm);
- start_time = vlib_time_now (vm);
- while (1)
- {
- if (vl_mem_api_handle_rpc (vm, node)
- || vl_mem_api_handle_msg_main (vm, node))
- {
- vm->api_queue_nonempty = 0;
- VL_MEM_API_LOG_Q_LEN ("q-underflow: len %d", 0);
- sleep_time = 20.0;
- break;
- }
-
- /* Allow no more than 10us without a pause */
- if (vlib_time_now (vm) > start_time + 10e-6)
- {
- int index = SLEEP_400_US;
- if (vector_rate > 40.0)
- sleep_time = 400e-6;
- else if (vector_rate > 20.0)
- {
- index = SLEEP_200_US;
- sleep_time = 200e-6;
- }
- else if (vector_rate >= 1.0)
- {
- index = SLEEP_100_US;
- sleep_time = 100e-6;
- }
- else
- {
- index = SLEEP_10_US;
- sleep_time = 10e-6;
- }
- vector_rate_histogram[index] += 1;
- break;
- }
- }
-
- /*
- * see if we have any private api shared-memory segments
- * If so, push required context variables, and process
- * a message.
- */
- if (PREDICT_FALSE (vec_len (am->vlib_private_rps)))
- {
- if (private_segment_rotor >= vec_len (am->vlib_private_rps))
- private_segment_rotor = 0;
- vl_mem_api_handle_msg_private (vm, node, private_segment_rotor++);
- }
-
- vlib_process_wait_for_event_or_clock (vm, sleep_time);
- vec_reset_length (event_data);
- event_type = vlib_process_get_events (vm, &event_data);
- now = vlib_time_now (vm);
-
- switch (event_type)
- {
- case QUEUE_SIGNAL_EVENT:
- vm->queue_signal_pending = 0;
- VL_MEM_API_LOG_Q_LEN ("q-awake: len %d", q->cursize);
-
- break;
- case SOCKET_READ_EVENT:
- for (i = 0; i < vec_len (event_data); i++)
- {
- vl_api_registration_t *regp;
-
- a = pool_elt_at_index (socket_main.process_args, event_data[i]);
- regp = vl_socket_get_registration (a->reg_index);
- if (regp)
- {
- vl_socket_process_api_msg (regp, (i8 *) a->data);
- a = pool_elt_at_index (socket_main.process_args,
- event_data[i]);
- }
- vec_free (a->data);
- pool_put (socket_main.process_args, a);
- }
- break;
-
- /* Timeout... */
- case -1:
- break;
-
- default:
- clib_warning ("unknown event type %d", event_type);
- break;
- }
-
- if (now > dead_client_scan_time)
- {
- vl_mem_api_dead_client_scan (am, shm, now);
- dead_client_scan_time = vlib_time_now (vm) + 10.0;
- }
- }