this will allow the user to control the behaviour better.
Signed-off-by: Angus Salkeld asalkeld@redhat.com --- include/qb/qbipcc.h | 10 ++++++++++ include/qb/qbipcs.h | 1 + lib/ipc_int.h | 1 + lib/ipcc.c | 17 ++++++++++++++--- lib/ipcs.c | 9 ++++++++- 5 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/include/qb/qbipcc.h b/include/qb/qbipcc.h index 0d71293..acecac9 100644 --- a/include/qb/qbipcc.h +++ b/include/qb/qbipcc.h @@ -88,6 +88,16 @@ void qb_ipcc_disconnect(qb_ipcc_connection_t* c); int32_t qb_ipcc_fd_get(qb_ipcc_connection_t* c, int32_t * fd);
/** + * Set the maximum allowable flowcontrol value. + * + * @note the default is 1 + * + * @param c connection instance + * @param max the max allowable flowcontrol value (1 or 2) + */ +int32_t qb_ipcc_fc_enable_max_set(qb_ipcc_connection_t * c, uint32_t max); + +/** * Send a message. * * @param c connection instance diff --git a/include/qb/qbipcs.h b/include/qb/qbipcs.h index eef90d2..aa8ce77 100644 --- a/include/qb/qbipcs.h +++ b/include/qb/qbipcs.h @@ -47,6 +47,7 @@ enum qb_ipcs_rate_limit { QB_IPCS_RATE_NORMAL, QB_IPCS_RATE_SLOW, QB_IPCS_RATE_OFF, + QB_IPCS_RATE_OFF_2, };
struct qb_ipcs_connection; diff --git a/lib/ipc_int.h b/lib/ipc_int.h index 0676989..e05c053 100644 --- a/lib/ipc_int.h +++ b/lib/ipc_int.h @@ -107,6 +107,7 @@ struct qb_ipcc_connection { struct qb_ipc_one_way event; struct qb_ipcc_funcs funcs; struct qb_ipc_request_header *receive_buf; + uint32_t fc_enable_max; };
int32_t qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c, diff --git a/lib/ipcc.c b/lib/ipcc.c index be09631..b63c676 100644 --- a/lib/ipcc.c +++ b/lib/ipcc.c @@ -49,6 +49,7 @@ qb_ipcc_connect(const char *name, size_t max_msg_size) c->request.max_msg_size = response.max_msg_size; c->event.max_msg_size = response.max_msg_size; c->receive_buf = malloc(response.max_msg_size); + c->fc_enable_max = 1; if (c->receive_buf == NULL) { res = -ENOMEM; goto disconnect_and_cleanup; @@ -97,7 +98,7 @@ qb_ipcc_send(struct qb_ipcc_connection * c, const void *msg_ptr, size_t msg_len) res = c->funcs.fc_get(&c->request); if (res < 0) { return res; - } else if (res > 0) { + } else if (res > 0 && res <= c->fc_enable_max) { return -EAGAIN; } else { /* @@ -121,6 +122,16 @@ qb_ipcc_send(struct qb_ipcc_connection * c, const void *msg_ptr, size_t msg_len) return res; }
+int32_t +qb_ipcc_fc_enable_max_set(struct qb_ipcc_connection * c, uint32_t max) +{ + if (c == NULL || max > 2) { + return -EINVAL; + } + c->fc_enable_max = max; + return 0; +} + ssize_t qb_ipcc_sendv(struct qb_ipcc_connection * c, const struct iovec * iov, size_t iov_len) @@ -141,7 +152,7 @@ qb_ipcc_sendv(struct qb_ipcc_connection * c, const struct iovec * iov, res = c->funcs.fc_get(&c->request); if (res < 0) { return res; - } else if (res > 0) { + } else if (res > 0 && res <= c->fc_enable_max) { return -EAGAIN; } else { /* @@ -202,7 +213,7 @@ qb_ipcc_sendv_recv(qb_ipcc_connection_t * c, res = c->funcs.fc_get(&c->request); if (res < 0) { return res; - } else if (res > 0) { + } else if (res > 0 && res <= c->fc_enable_max) { return -EAGAIN; } else { /* diff --git a/lib/ipcs.c b/lib/ipcs.c index cf014d4..b1d64c7 100644 --- a/lib/ipcs.c +++ b/lib/ipcs.c @@ -154,6 +154,7 @@ qb_ipcs_request_rate_limit(struct qb_ipcs_service *s, break; case QB_IPCS_RATE_SLOW: case QB_IPCS_RATE_OFF: + case QB_IPCS_RATE_OFF_2: s->poll_priority = QB_LOOP_LOW; break; default: @@ -168,7 +169,13 @@ qb_ipcs_request_rate_limit(struct qb_ipcs_service *s, c = qb_list_entry(pos, struct qb_ipcs_connection, list); qb_ipcs_connection_ref(c);
- qb_ipcs_flowcontrol_set(c, (rl == QB_IPCS_RATE_OFF)); + if (rl == QB_IPCS_RATE_OFF) { + qb_ipcs_flowcontrol_set(c, 1); + } else if (rl == QB_IPCS_RATE_OFF_2) { + qb_ipcs_flowcontrol_set(c, 2); + } else { + qb_ipcs_flowcontrol_set(c, QB_FALSE); + } if (old_p != s->poll_priority) { (void)_modify_dispatch_descriptor_(c); }