IPC: change the ipcs_connection to a pointer (not handle).

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@redhat.com>
This commit is contained in:
Angus Salkeld 2010-10-01 22:10:01 +10:00
parent 2aae94eb1d
commit fcd0ca69d9
5 changed files with 69 additions and 58 deletions

View File

@ -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

View File

@ -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;

View File

@ -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.");

View File

@ -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;
}

View File

@ -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");