Mainly to be consistent with the other objects.
Also:
- splint warnings(-weak) are now zero.
- Added a reference counter to replace the handle.
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
configure.ac | 2 -
include/qb/qbipcs.h | 40 ++++++++++++++++-----
lib/ipc_int.h | 2 +
lib/ipcs.c | 95 ++++++++++++++++++++-------------------------------
tests/bms.c | 2 +-
tests/check_ipc.c | 2 +-
6 files changed, 72 insertions(+), 71 deletions(-)
diff --git a/configure.ac b/configure.ac
index 0003c33..24d1659 100644
--- a/configure.ac
+++ b/configure.ac
@@ -241,7 +241,6 @@ case "$host_os" in
*linux*)
AC_DEFINE_UNQUOTED([QB_LINUX], [1],
[Compiling for Linux platform])
- LINT_FLAGS+=" -expect 21"
;;
darwin*)
AC_DEFINE_UNQUOTED([QB_DARWIN], [1],
@@ -269,7 +268,6 @@ case "$host_os" in
[Compiling for FreeBSD >= 8 platform])
;;
esac
- LINT_FLAGS="$LINT_FLAGS -expect 22"
;;
*solaris*)
AC_DEFINE_UNQUOTED([QB_SOLARIS], [1],
diff --git a/include/qb/qbipcs.h b/include/qb/qbipcs.h
index 9e23ae7..7d14ef5 100644
--- a/include/qb/qbipcs.h
+++ b/include/qb/qbipcs.h
@@ -44,7 +44,8 @@ enum qb_ipcs_rate_limit {
struct qb_ipcs_connection;
typedef struct qb_ipcs_connection qb_ipcs_connection_t;
-typedef qb_handle_t qb_ipcs_service_pt;
+struct qb_ipcs_service;
+typedef struct qb_ipcs_service qb_ipcs_service_t;
struct qb_ipcs_stats {
uint32_t active_connections;
@@ -125,17 +126,38 @@ struct qb_ipcs_service_handlers {
/**
* Create a new IPC server.
+ *
+ * @param name for clients to connect to.
+ * @param service_id an integer to associate with the service
+ * @param type transport type.
+ * @param handlers callbacks.
+ * @return the new service instance.
*/
-qb_ipcs_service_pt qb_ipcs_create(const char *name,
+qb_ipcs_service_t* qb_ipcs_create(const char *name,
int32_t service_id,
enum qb_ipc_type type,
struct qb_ipcs_service_handlers *handlers);
+
+/**
+ * Increase the reference counter on the service object.
+ *
+ * @param s service instance
+ */
+void qb_ipcs_ref(qb_ipcs_service_t *s);
+
+/**
+ * Decrease the reference counter on the service object.
+ *
+ * @param s service instance
+ */
+void qb_ipcs_unref(qb_ipcs_service_t *s);
+
/**
* Set your poll callbacks.
* @param s service instance
*/
-void qb_ipcs_poll_handlers_set(qb_ipcs_service_pt s,
+void qb_ipcs_poll_handlers_set(qb_ipcs_service_t* s,
struct qb_ipcs_poll_handlers *handlers);
/**
@@ -143,19 +165,19 @@ void qb_ipcs_poll_handlers_set(qb_ipcs_service_pt s,
* @param s service instance
* @return 0 == ok; -errno to indicate a failure
*/
-int32_t qb_ipcs_run(qb_ipcs_service_pt s);
+int32_t qb_ipcs_run(qb_ipcs_service_t* s);
/**
* Destroy the IPC server.
* @param s service instance
*/
-void qb_ipcs_destroy(qb_ipcs_service_pt s);
+void qb_ipcs_destroy(qb_ipcs_service_t* s);
/**
*
* @param s service instance
*/
-void qb_ipcs_request_rate_limit(qb_ipcs_service_pt pt, enum qb_ipcs_rate_limit rl);
+void qb_ipcs_request_rate_limit(qb_ipcs_service_t* pt, enum qb_ipcs_rate_limit rl);
/**
* send a response to a incomming request.
@@ -232,7 +254,7 @@ int32_t qb_ipcs_connection_stats_get(qb_ipcs_connection_t *c,
* @param pt service instance
* @return 0 == ok; -errno to indicate a failure
*/
-int32_t qb_ipcs_stats_get(qb_ipcs_service_pt pt,
+int32_t qb_ipcs_stats_get(qb_ipcs_service_t* pt,
struct qb_ipcs_stats* stats,
int32_t clear_after_read);
@@ -244,7 +266,7 @@ int32_t qb_ipcs_stats_get(qb_ipcs_service_pt pt,
* @param pt service instance
* @return first connection
*/
-qb_ipcs_connection_t * qb_ipcs_connection_first_get(qb_ipcs_service_pt pt);
+qb_ipcs_connection_t * qb_ipcs_connection_first_get(qb_ipcs_service_t* pt);
/**
* Get the next connection.
@@ -255,7 +277,7 @@ qb_ipcs_connection_t * qb_ipcs_connection_first_get(qb_ipcs_service_pt
pt);
* @param current current connection
* @return next connection
*/
-qb_ipcs_connection_t * qb_ipcs_connection_next_get(qb_ipcs_service_pt pt,
+qb_ipcs_connection_t * qb_ipcs_connection_next_get(qb_ipcs_service_t* pt,
qb_ipcs_connection_t *current);
/* *INDENT-OFF* */
diff --git a/lib/ipc_int.h b/lib/ipc_int.h
index 70290be..01f9ead 100644
--- a/lib/ipc_int.h
+++ b/lib/ipc_int.h
@@ -142,6 +142,7 @@ struct qb_ipcs_service {
enum qb_ipc_type type;
char name[NAME_MAX];
int32_t service_id;
+ int32_t ref_count;
pid_t pid;
int32_t needs_sock_for_poll;
int32_t server_sock;
@@ -152,6 +153,7 @@ struct qb_ipcs_service {
enum qb_loop_priority poll_priority;
struct qb_list_head connections;
+ struct qb_list_head list;
struct qb_ipcs_stats stats;
};
diff --git a/lib/ipcs.c b/lib/ipcs.c
index 5d47d49..0b1d3d9 100644
--- a/lib/ipcs.c
+++ b/lib/ipcs.c
@@ -26,28 +26,25 @@
#include <qb/qbatomic.h>
#include <qb/qbipcs.h>
-static void qb_ipcs_destroy_internal(void *data);
static void qb_ipcs_flowcontrol_set(struct qb_ipcs_connection *c,
int32_t fc_enable);
-QB_HDB_DECLARE(qb_ipc_services, qb_ipcs_destroy_internal);
+static QB_LIST_DECLARE(qb_ipc_services);
-qb_ipcs_service_pt qb_ipcs_create(const char *name,
+qb_ipcs_service_t* qb_ipcs_create(const char *name,
int32_t service_id,
enum qb_ipc_type type,
struct qb_ipcs_service_handlers *handlers)
{
struct qb_ipcs_service *s;
- qb_ipcs_service_pt h;
- qb_hdb_handle_create(&qb_ipc_services,
- sizeof(struct qb_ipcs_service), &h);
- qb_hdb_handle_get(&qb_ipc_services, h, (void **)&s);
+ s = calloc(1, sizeof(struct qb_ipcs_service));
s->pid = getpid();
s->type = type;
s->needs_sock_for_poll = QB_FALSE;
s->poll_priority = QB_LOOP_MED;
+ s->ref_count = 1;
s->service_id = service_id;
strncpy(s->name, name, NAME_MAX);
@@ -58,33 +55,24 @@ qb_ipcs_service_pt qb_ipcs_create(const char *name,
s->serv_fns.connection_destroyed = handlers->connection_destroyed;
qb_list_init(&s->connections);
+ qb_list_init(&s->list);
+ qb_list_add(&s->list, &qb_ipc_services);
- qb_hdb_handle_put(&qb_ipc_services, h);
-
- return h;
+ return s;
}
-void qb_ipcs_poll_handlers_set(qb_ipcs_service_pt pt,
+void qb_ipcs_poll_handlers_set(struct qb_ipcs_service* s,
struct qb_ipcs_poll_handlers *handlers)
{
- struct qb_ipcs_service *s;
-
- qb_hdb_handle_get(&qb_ipc_services, pt, (void **)&s);
-
s->poll_fns.job_add = handlers->job_add;
s->poll_fns.dispatch_add = handlers->dispatch_add;
s->poll_fns.dispatch_mod = handlers->dispatch_mod;
s->poll_fns.dispatch_del = handlers->dispatch_del;
-
- qb_hdb_handle_put(&qb_ipc_services, pt);
}
-int32_t qb_ipcs_run(qb_ipcs_service_pt pt)
+int32_t qb_ipcs_run(struct qb_ipcs_service* s)
{
int32_t res;
- struct qb_ipcs_service *s;
-
- qb_hdb_handle_get(&qb_ipc_services, pt, (void **)&s);
switch (s->type) {
case QB_IPC_SOCKET:
@@ -105,21 +93,19 @@ int32_t qb_ipcs_run(qb_ipcs_service_pt pt)
}
res = qb_ipcs_us_publish(s);
if (res < 0) {
- qb_hdb_handle_put(&qb_ipc_services, pt);
+ qb_ipcs_unref(s);
return res;
}
if (res < 0) {
- qb_ipcs_us_withdraw(s);
+ (void)qb_ipcs_us_withdraw(s);
}
- qb_hdb_handle_put(&qb_ipc_services, pt);
return res;
}
-void qb_ipcs_request_rate_limit(qb_ipcs_service_pt pt, enum qb_ipcs_rate_limit rl)
+void qb_ipcs_request_rate_limit(struct qb_ipcs_service* s, enum qb_ipcs_rate_limit rl)
{
- struct qb_ipcs_service *s;
struct qb_ipcs_connection *c;
enum qb_loop_priority p;
@@ -137,8 +123,6 @@ void qb_ipcs_request_rate_limit(qb_ipcs_service_pt pt, enum
qb_ipcs_rate_limit r
break;
}
- qb_hdb_handle_get(&qb_ipc_services, pt, (void**)&s);
-
qb_list_for_each_entry(c, &s->connections, list) {
qb_ipcs_connection_ref_inc(c);
@@ -166,33 +150,40 @@ void qb_ipcs_request_rate_limit(qb_ipcs_service_pt pt, enum
qb_ipcs_rate_limit r
qb_ipcs_connection_ref_dec(c);
}
s->poll_priority = p;
- qb_hdb_handle_put(&qb_ipc_services, pt);
}
-void qb_ipcs_destroy(qb_ipcs_service_pt pt)
+void qb_ipcs_ref(struct qb_ipcs_service *s)
{
- qb_hdb_handle_put(&qb_ipc_services, pt);
- qb_hdb_handle_destroy(&qb_ipc_services, pt);
+ qb_atomic_int_inc(&s->ref_count);
}
-static void qb_ipcs_destroy_internal(void *data)
+void qb_ipcs_unref(struct qb_ipcs_service *s)
{
- struct qb_ipcs_service *s = (struct qb_ipcs_service *)data;
+ int32_t free_it;
struct qb_ipcs_connection *c = NULL;
struct qb_list_head *iter;
struct qb_list_head *iter_next;
- qb_util_log(LOG_DEBUG, "%s\n", __func__);
-
- qb_list_for_each_safe(iter, iter_next, &s->connections) {
- c = qb_list_entry(iter, struct qb_ipcs_connection, list);
- if (c == NULL) {
- continue;
+ assert(s->ref_count > 0);
+ free_it = qb_atomic_int_dec_and_test(&s->ref_count);
+ if (free_it) {
+ qb_util_log(LOG_DEBUG, "%s() - destorying\n", __func__);
+ qb_list_for_each_safe(iter, iter_next, &s->connections) {
+ c = qb_list_entry(iter, struct qb_ipcs_connection, list);
+ if (c == NULL) {
+ continue;
+ }
+ qb_ipcs_disconnect(c);
}
- qb_ipcs_disconnect(c);
+ free(s);
}
}
+void qb_ipcs_destroy(struct qb_ipcs_service* s)
+{
+ qb_ipcs_unref(s);
+}
+
/*
* connection API
*/
@@ -299,44 +290,36 @@ ssize_t qb_ipcs_event_sendv(struct qb_ipcs_connection *c, const
struct iovec * i
return res;
}
-qb_ipcs_connection_t * qb_ipcs_connection_first_get(qb_ipcs_service_pt pt)
+qb_ipcs_connection_t * qb_ipcs_connection_first_get(struct qb_ipcs_service* s)
{
- struct qb_ipcs_service *s;
struct qb_ipcs_connection *c;
struct qb_list_head *iter;
- qb_hdb_handle_get(&qb_ipc_services, pt, (void **)&s);
-
if (qb_list_empty(&s->connections)) {
- qb_hdb_handle_put(&qb_ipc_services, pt);
return NULL;
}
iter = s->connections.next;
c = qb_list_entry(iter, struct qb_ipcs_connection, list);
qb_ipcs_connection_ref_inc(c);
- qb_hdb_handle_put(&qb_ipc_services, pt);
+
return c;
}
-qb_ipcs_connection_t * qb_ipcs_connection_next_get(qb_ipcs_service_pt pt,
+qb_ipcs_connection_t * qb_ipcs_connection_next_get(struct qb_ipcs_service* s,
struct qb_ipcs_connection *current)
{
- struct qb_ipcs_service *s;
struct qb_ipcs_connection *c;
struct qb_list_head *iter;
- qb_hdb_handle_get(&qb_ipc_services, pt, (void **)&s);
-
if (current->list.next == &s->connections) {
- qb_hdb_handle_put(&qb_ipc_services, pt);
return NULL;
}
iter = current->list.next;
c = qb_list_entry(iter, struct qb_ipcs_connection, list);
qb_ipcs_connection_ref_inc(c);
- qb_hdb_handle_put(&qb_ipc_services, pt);
+
return c;
}
@@ -588,18 +571,14 @@ int32_t qb_ipcs_connection_stats_get(qb_ipcs_connection_t *c,
return 0;
}
-int32_t qb_ipcs_stats_get(qb_ipcs_service_pt pt,
+int32_t qb_ipcs_stats_get(struct qb_ipcs_service* s,
struct qb_ipcs_stats* stats,
int32_t clear_after_read)
{
- struct qb_ipcs_service *s;
-
- qb_hdb_handle_get(&qb_ipc_services, pt, (void **)&s);
memcpy(stats, &s->stats, sizeof(struct qb_ipcs_stats));
if (clear_after_read) {
memset(&s->stats, 0, sizeof(struct qb_ipcs_stats));
}
- qb_hdb_handle_put(&qb_ipc_services, pt);
return 0;
}
diff --git a/tests/bms.c b/tests/bms.c
index 80d3561..65010dc 100644
--- a/tests/bms.c
+++ b/tests/bms.c
@@ -39,7 +39,7 @@ static qb_loop_t *bms_loop;
static GMainLoop *glib_loop;
static qb_array_t *gio_map;
#endif
-static qb_ipcs_service_pt s1;
+static qb_ipcs_service_t* s1;
static int32_t s1_connection_accept_fn(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
{
diff --git a/tests/check_ipc.c b/tests/check_ipc.c
index b97e91c..ca20239 100644
--- a/tests/check_ipc.c
+++ b/tests/check_ipc.c
@@ -68,7 +68,7 @@ enum my_msg_ids {
* 8) multiple services
*/
static qb_loop_t *my_loop;
-static qb_ipcs_service_pt s1;
+static qb_ipcs_service_t* s1;
static int32_t turn_on_fc = QB_FALSE;
static int32_t fc_enabled = 89;
--
1.7.3.1