diff --git a/include/qb/qbipcs.h b/include/qb/qbipcs.h index 0a4caed..2bbe22e 100644 --- a/include/qb/qbipcs.h +++ b/include/qb/qbipcs.h @@ -73,6 +73,18 @@ struct qb_ipcs_connection_stats { uint64_t flow_control_count; }; +struct qb_ipcs_connection_stats_2 { + int32_t client_pid; + uint64_t requests; + uint64_t responses; + uint64_t events; + uint64_t send_retries; + uint64_t recv_retries; + int32_t flow_control_state; + uint64_t flow_control_count; + uint32_t event_q_length; +}; + typedef int32_t (*qb_ipcs_dispatch_fn_t) (int32_t fd, int32_t revents, void *data); @@ -310,6 +322,7 @@ void *qb_ipcs_context_get(qb_ipcs_connection_t *c); /** * Get the connection statistics. * + * @deprecated from v0.13.0 onwards, use qb_ipcs_connection_stats_get_2 * @param stats (out) the statistics structure * @param clear_after_read clear stats after copying them into stats * @param c connection instance @@ -318,6 +331,17 @@ void *qb_ipcs_context_get(qb_ipcs_connection_t *c); int32_t qb_ipcs_connection_stats_get(qb_ipcs_connection_t *c, struct qb_ipcs_connection_stats* stats, int32_t clear_after_read); +/** + * Get (and allocate) the connection statistics. + * + * @param clear_after_read clear stats after copying them into stats + * @param c connection instance + * @retval NULL if no memory or invalid connection + * @retval allocated statistics structure (user must free it). + */ +struct qb_ipcs_connection_stats_2* +qb_ipcs_connection_stats_get_2(qb_ipcs_connection_t *c, + int32_t clear_after_read); /** * Get the service statistics. diff --git a/lib/ipc_int.h b/lib/ipc_int.h index 5e0acde..d90443c 100644 --- a/lib/ipc_int.h +++ b/lib/ipc_int.h @@ -186,7 +186,7 @@ struct qb_ipcs_connection { int32_t fc_enabled; int32_t poll_events; int32_t outstanding_notifiers; - struct qb_ipcs_connection_stats stats; + struct qb_ipcs_connection_stats_2 stats; }; void qb_ipcs_pmq_init(struct qb_ipcs_service *s); diff --git a/lib/ipcs.c b/lib/ipcs.c index b385220..84f32c0 100644 --- a/lib/ipcs.c +++ b/lib/ipcs.c @@ -751,12 +751,41 @@ qb_ipcs_connection_stats_get(qb_ipcs_connection_t * c, } memcpy(stats, &c->stats, sizeof(struct qb_ipcs_connection_stats)); if (clear_after_read) { - memset(&c->stats, 0, sizeof(struct qb_ipcs_connection_stats)); + memset(&c->stats, 0, sizeof(struct qb_ipcs_connection_stats_2)); c->stats.client_pid = c->pid; } return 0; } +struct qb_ipcs_connection_stats_2* +qb_ipcs_connection_stats_get_2(qb_ipcs_connection_t *c, + int32_t clear_after_read) +{ + struct qb_ipcs_connection_stats_2* stats; + + if (c == NULL) { + errno = EINVAL; + return NULL; + } + stats = calloc(1, sizeof(struct qb_ipcs_connection_stats_2)); + if (stats == NULL) { + return NULL; + } + + memcpy(stats, &c->stats, sizeof(struct qb_ipcs_connection_stats_2)); + + if (c->service->funcs.q_len_get) { + stats->event_q_length = c->service->funcs.q_len_get(&c->event); + } else { + stats->event_q_length = 0; + } + if (clear_after_read) { + memset(&c->stats, 0, sizeof(struct qb_ipcs_connection_stats_2)); + c->stats.client_pid = c->pid; + } + return stats; +} + int32_t qb_ipcs_stats_get(struct qb_ipcs_service * s, struct qb_ipcs_stats * stats, int32_t clear_after_read) diff --git a/tests/check_ipc.c b/tests/check_ipc.c index 1ea59ed..e2fe947 100644 --- a/tests/check_ipc.c +++ b/tests/check_ipc.c @@ -118,13 +118,14 @@ s1_msg_process_fn(qb_ipcs_connection_t *c, } else if (req_pt->id == IPC_MSG_REQ_BULK_EVENTS) { int32_t m; int32_t num; - struct qb_ipcs_connection_stats stats; + struct qb_ipcs_connection_stats_2 *stats; response.size = sizeof(struct qb_ipc_response_header); response.error = 0; - qb_ipcs_connection_stats_get(c, &stats, QB_FALSE); - num = stats.event_q_length; + stats = qb_ipcs_connection_stats_get_2(c, QB_FALSE); + num = stats->event_q_length; + free(stats); for (m = 0; m < num_bulk_events; m++) { res = qb_ipcs_event_send(c, &response, @@ -132,8 +133,9 @@ s1_msg_process_fn(qb_ipcs_connection_t *c, ck_assert_int_eq(res, sizeof(response)); response.id++; } - qb_ipcs_connection_stats_get(c, &stats, QB_FALSE); - ck_assert_int_eq(stats.event_q_length - num, num_bulk_events); + stats = qb_ipcs_connection_stats_get_2(c, QB_FALSE); + ck_assert_int_eq(stats->event_q_length - num, num_bulk_events); + free(stats); response.id = IPC_MSG_RES_BULK_EVENTS; res = qb_ipcs_response_send(c, &response, response.size);