This is make integrating with corosync easier.
Also technically it doesn't really matter it still
has a reference counter.
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
include/qb/qbipcs.h | 28 +++++++++++++----
lib/ipc_int.h | 2 +-
lib/ipc_us.c | 4 +-
lib/ipcs.c | 83 ++++++++++++++++++++++++--------------------------
tests/bms.c | 10 +++---
5 files changed, 69 insertions(+), 58 deletions(-)
diff --git a/include/qb/qbipcs.h b/include/qb/qbipcs.h
index b1dc6d9..f8df928 100644
--- a/include/qb/qbipcs.h
+++ b/include/qb/qbipcs.h
@@ -33,7 +33,9 @@ extern "C" {
#endif
/* *INDENT-ON* */
-typedef qb_handle_t qb_ipcs_connection_handle_t;
+struct qb_ipcs_connection;
+typedef struct qb_ipcs_connection qb_ipcs_connection_t;
+
typedef qb_handle_t qb_ipcs_service_pt;
typedef int32_t (*qb_ipcs_dispatch_fn_t) (qb_ipcs_service_pt s, int32_t fd, int32_t
revents,
@@ -56,21 +58,21 @@ struct qb_ipcs_poll_handlers {
* or process resource constraints.
* @return 0 to accept or -errno to indicate a failure (sent back to the client)
*/
-typedef int32_t (*qb_ipcs_connection_accept_fn) (qb_ipcs_connection_handle_t c, uid_t
uid, gid_t gid);
+typedef int32_t (*qb_ipcs_connection_accept_fn) (qb_ipcs_connection_t *c, uid_t uid,
gid_t gid);
/**
* This is called after a new connection has been created.
*/
-typedef void (*qb_ipcs_connection_created_fn) (qb_ipcs_connection_handle_t c);
+typedef void (*qb_ipcs_connection_created_fn) (qb_ipcs_connection_t *c);
/**
* This is called after a connection has been destroyed.
*/
-typedef void (*qb_ipcs_connection_destroyed_fn) (qb_ipcs_connection_handle_t c);
+typedef void (*qb_ipcs_connection_destroyed_fn) (qb_ipcs_connection_t *c);
/**
* This is the message processing calback.
* It is called with the message data.
*/
-typedef void (*qb_ipcs_msg_process_fn) (qb_ipcs_connection_handle_t c,
+typedef void (*qb_ipcs_msg_process_fn) (qb_ipcs_connection_t *c,
void *data, size_t size);
struct qb_ipcs_service_handlers {
@@ -108,12 +110,24 @@ void qb_ipcs_destroy(qb_ipcs_service_pt s);
/**
* send a response to a incomming request.
*/
-ssize_t qb_ipcs_response_send(qb_ipcs_connection_handle_t c, void *data, size_t size);
+ssize_t qb_ipcs_response_send(qb_ipcs_connection_t *c, void *data, size_t size);
/**
* Send an asyncronous event message to the client.
*/
-ssize_t qb_ipcs_event_send(qb_ipcs_connection_handle_t c, void *data, size_t size);
+ssize_t qb_ipcs_event_send(qb_ipcs_connection_t *c, void *data, size_t size);
+
+
+/**
+ * Increment the connection's reference counter.
+ */
+void qb_ipcs_connection_ref_inc(qb_ipcs_connection_t *c);
+
+/**
+ * Decrement the connection's reference counter.
+ */
+void qb_ipcs_connection_ref_dec(qb_ipcs_connection_t *c);
+
/* *INDENT-OFF* */
#ifdef __cplusplus
diff --git a/lib/ipc_int.h b/lib/ipc_int.h
index 131232a..d03bcac 100644
--- a/lib/ipc_int.h
+++ b/lib/ipc_int.h
@@ -157,7 +157,7 @@ struct qb_ipcs_service {
};
struct qb_ipcs_connection {
- qb_ipcs_connection_handle_t handle;
+ int32_t refcount;
pid_t pid;
uid_t euid;
gid_t egid;
diff --git a/lib/ipc_us.c b/lib/ipc_us.c
index 49781b7..184eaa0 100644
--- a/lib/ipc_us.c
+++ b/lib/ipc_us.c
@@ -265,7 +265,7 @@ cleanup_and_return:
if (res == 0) {
if (c->service->serv_fns.connection_accept) {
- res = c->service->serv_fns.connection_accept(c->handle,
+ res = c->service->serv_fns.connection_accept(c,
c->euid,
c->egid);
} else {
@@ -578,7 +578,7 @@ send_response:
if (res == 0) {
if (s->serv_fns.connection_created) {
- s->serv_fns.connection_created(c->handle);
+ s->serv_fns.connection_created(c);
}
} else if (res == -EACCES) {
qb_util_log(LOG_ERR, "Invalid IPC credentials.");
diff --git a/lib/ipcs.c b/lib/ipcs.c
index 65997a7..909318f 100644
--- a/lib/ipcs.c
+++ b/lib/ipcs.c
@@ -25,10 +25,8 @@
#include <qb/qbipcs.h>
static void qb_ipcs_destroy_internal(void *data);
-static void qb_ipcs_disconnect_internal(void *data);
QB_HDB_DECLARE(qb_ipc_services, qb_ipcs_destroy_internal);
-QB_HDB_DECLARE(qb_ipc_connections, qb_ipcs_disconnect_internal);
qb_ipcs_service_pt qb_ipcs_create(const char *name, enum qb_ipc_type type)
{
@@ -132,53 +130,40 @@ static void qb_ipcs_destroy_internal(void *data)
s->funcs.destroy(s);
}
-ssize_t qb_ipcs_response_send(qb_ipcs_connection_handle_t c, void *data,
+ssize_t qb_ipcs_response_send(struct qb_ipcs_connection *c, void *data,
size_t size)
{
ssize_t res;
- struct qb_ipcs_connection *con;
- res = qb_hdb_handle_get(&qb_ipc_connections, c, (void **)&con);
- if (res < 0) {
- return res;
- }
- res = con->service->funcs.response_send(con, data, size);
- qb_hdb_handle_put(&qb_ipc_connections, c);
+ qb_ipcs_connection_ref_inc(c);
+ res = c->service->funcs.response_send(c, data, size);
+ qb_ipcs_connection_ref_dec(c);
return res;
}
-ssize_t qb_ipcs_event_send(qb_ipcs_connection_handle_t c, void *data,
+ssize_t qb_ipcs_event_send(struct qb_ipcs_connection *c, void *data,
size_t size)
{
ssize_t res;
- struct qb_ipcs_connection *con;
- res = qb_hdb_handle_get(&qb_ipc_connections, c, (void **)&con);
- if (res < 0) {
- return res;
- }
- res = con->service->funcs.event_send(con, data, size);
+ qb_ipcs_connection_ref_inc(c);
+ res = c->service->funcs.event_send(c, data, size);
- if (con->service->needs_sock_for_poll) {
- qb_ipc_us_send(con->sock, data, 1);
+ if (c->service->needs_sock_for_poll) {
+ qb_ipc_us_send(c->sock, data, 1);
}
- qb_hdb_handle_put(&qb_ipc_connections, c);
+ qb_ipcs_connection_ref_dec(c);
return res;
}
struct qb_ipcs_connection *qb_ipcs_connection_alloc(struct qb_ipcs_service *s)
{
- qb_ipcs_connection_handle_t h;
- struct qb_ipcs_connection *c;
+ struct qb_ipcs_connection *c = malloc(sizeof(struct qb_ipcs_connection));
- qb_hdb_handle_create(&qb_ipc_connections,
- sizeof(struct qb_ipcs_connection), &h);
- qb_hdb_handle_get(&qb_ipc_connections, h, (void **)&c);
-
- c->handle = h;
+ c->refcount = 1;
c->service = s;
c->pid = 0;
c->euid = -1;
@@ -190,29 +175,39 @@ struct qb_ipcs_connection *qb_ipcs_connection_alloc(struct
qb_ipcs_service *s)
return c;
}
-static void qb_ipcs_disconnect_internal(void *data)
+void qb_ipcs_connection_ref_inc(struct qb_ipcs_connection *c)
{
- struct qb_ipcs_connection *c = (struct qb_ipcs_connection *)data;
+ // lock
+ c->refcount++;
+ qb_util_log(LOG_DEBUG, "%s() %d", __func__, c->refcount);
+ // unlock
+}
- qb_util_log(LOG_DEBUG, "%s()", __func__);
- qb_list_del(&c->list);
- if (c->service->serv_fns.connection_destroyed) {
- c->service->serv_fns.connection_destroyed(c->handle);
- }
- c->service->funcs.disconnect(c);
- qb_ipcc_us_disconnect(c->sock);
- if (c->receive_buf) {
- free(c->receive_buf);
+void qb_ipcs_connection_ref_dec(struct qb_ipcs_connection *c)
+{
+ // lock
+ c->refcount--;
+ qb_util_log(LOG_DEBUG, "%s() %d", __func__, c->refcount);
+ if (c->refcount == 0) {
+ qb_list_del(&c->list);
+ // unlock
+ if (c->service->serv_fns.connection_destroyed) {
+ c->service->serv_fns.connection_destroyed(c);
+ }
+ c->service->funcs.disconnect(c);
+ qb_ipcc_us_disconnect(c->sock);
+ if (c->receive_buf) {
+ free(c->receive_buf);
+ }
+ } else {
+ // unlock
}
}
void qb_ipcs_disconnect(struct qb_ipcs_connection *c)
{
qb_util_log(LOG_DEBUG, "%s()", __func__);
- if (qb_hdb_handle_destroy(&qb_ipc_connections, c->handle) != 0)
- perror("qb_ipcs_disconnect:destroy");
- if (qb_hdb_handle_put(&qb_ipc_connections, c->handle) != 0)
- perror("qb_ipcs_disconnect:put");
+ qb_ipcs_connection_ref_dec(c);
}
static int32_t _process_request_(struct qb_ipcs_connection *c)
@@ -222,6 +217,7 @@ static int32_t _process_request_(struct qb_ipcs_connection *c)
hdr = (struct qb_ipc_request_header *)c->receive_buf;
+ qb_ipcs_connection_ref_inc(c);
get_msg_with_live_connection:
res = c->service->funcs.request_recv(c, hdr, c->max_msg_size);
if (res == -EAGAIN) {
@@ -240,10 +236,11 @@ get_msg_with_live_connection:
case QB_IPC_MSG_NEW_MESSAGE:
default:
- c->service->serv_fns.msg_process(c->handle, hdr, hdr->size);
+ c->service->serv_fns.msg_process(c, hdr, hdr->size);
break;
}
cleanup:
+ qb_ipcs_connection_ref_dec(c);
return res;
}
diff --git a/tests/bms.c b/tests/bms.c
index e770990..188532d 100644
--- a/tests/bms.c
+++ b/tests/bms.c
@@ -52,7 +52,7 @@ int32_t verbose = 0;
static qb_handle_t bms_poll_handle;
static qb_ipcs_service_pt s1;
-static int32_t s1_connection_accept_fn(qb_ipcs_connection_handle_t conn, uid_t uid, gid_t
gid)
+static int32_t s1_connection_accept_fn(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
{
#if 0
if (uid == 0 && gid == 0) {
@@ -70,20 +70,20 @@ static int32_t s1_connection_accept_fn(qb_ipcs_connection_handle_t
conn, uid_t u
}
-static void s1_connection_created_fn(qb_ipcs_connection_handle_t conn)
+static void s1_connection_created_fn(qb_ipcs_connection_t *c)
{
if (verbose) {
printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
}
}
-static void s1_connection_destroyed_fn(qb_ipcs_connection_handle_t conn)
+static void s1_connection_destroyed_fn(qb_ipcs_connection_t *c)
{
if (verbose) {
printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
}
}
-static void s1_msg_process_fn(qb_ipcs_connection_handle_t conn,
+static void s1_msg_process_fn(qb_ipcs_connection_t *c,
void *data, size_t size)
{
struct qb_ipc_request_header *req_pt = (struct qb_ipc_request_header *)data;
@@ -99,7 +99,7 @@ static void s1_msg_process_fn(qb_ipcs_connection_handle_t conn,
response.id = 13;
response.error = 0;
if (blocking == 1) {
- res = qb_ipcs_response_send(conn, &response,
+ res = qb_ipcs_response_send(c, &response,
sizeof(response));
if (res < 0) {
perror("qb_ipcs_response_send");
--
1.7.2.3