more consistant connection types (and their use)
parent
12427217c6
commit
74fea778f7
|
@ -110,7 +110,7 @@ int accept_new_client (int serverfd)
|
||||||
EXIT_FAILURE);
|
EXIT_FAILURE);
|
||||||
|
|
||||||
// adding a client
|
// adding a client
|
||||||
ipc_add_fd (ctx, sock_fd_client);
|
ipc_add_fd_switched (ctx, sock_fd_client);
|
||||||
|
|
||||||
return sock_fd_client;
|
return sock_fd_client;
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,13 +276,12 @@ struct ipc_error ipc_del (struct ipc_ctx *ctx, uint32_t index)
|
||||||
IPC_RETURN_NO_ERROR;
|
IPC_RETURN_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add an arbitrary file descriptor to read
|
struct ipc_error ipc_add_fd_ (struct ipc_ctx *ctx, int fd, enum ipc_connection_type type)
|
||||||
struct ipc_error ipc_add_fd (struct ipc_ctx *ctx, int fd)
|
|
||||||
{
|
{
|
||||||
T_R ((ctx == NULL), IPC_ERROR_ADD_FD__NO_PARAM_CINFOS);
|
T_R ((ctx == NULL), IPC_ERROR_ADD_FD__NO_PARAM_CINFOS);
|
||||||
|
|
||||||
SECURE_DECLARATION (struct ipc_connection_info, cinfo);
|
SECURE_DECLARATION (struct ipc_connection_info, cinfo);
|
||||||
cinfo.type = IPC_CONNECTION_TYPE_EXTERNAL;
|
cinfo.type = type;
|
||||||
|
|
||||||
SECURE_DECLARATION (struct pollfd, pollfd);
|
SECURE_DECLARATION (struct pollfd, pollfd);
|
||||||
pollfd.fd = fd;
|
pollfd.fd = fd;
|
||||||
|
@ -291,6 +290,18 @@ struct ipc_error ipc_add_fd (struct ipc_ctx *ctx, int fd)
|
||||||
return ipc_add (ctx, &cinfo, &pollfd);
|
return ipc_add (ctx, &cinfo, &pollfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add a switched file descriptor to read
|
||||||
|
struct ipc_error ipc_add_fd_switched (struct ipc_ctx *ctx, int fd)
|
||||||
|
{
|
||||||
|
return ipc_add_fd_ (ctx, fd, IPC_CONNECTION_TYPE_SWITCHED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add an arbitrary file descriptor to read
|
||||||
|
struct ipc_error ipc_add_fd (struct ipc_ctx *ctx, int fd)
|
||||||
|
{
|
||||||
|
return ipc_add_fd_ (ctx, fd, IPC_CONNECTION_TYPE_EXTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
// remove a connection from its file descriptor
|
// remove a connection from its file descriptor
|
||||||
struct ipc_error ipc_del_fd (struct ipc_ctx *ctx, int fd)
|
struct ipc_error ipc_del_fd (struct ipc_ctx *ctx, int fd)
|
||||||
{
|
{
|
||||||
|
@ -306,7 +317,6 @@ struct ipc_error ipc_del_fd (struct ipc_ctx *ctx, int fd)
|
||||||
IPC_RETURN_ERROR (IPC_ERROR_DEL_FD__CANNOT_FIND_CLIENT);
|
IPC_RETURN_ERROR (IPC_ERROR_DEL_FD__CANNOT_FIND_CLIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ipc_error handle_writing_message (struct ipc_event *event, struct ipc_ctx *ctx, uint32_t index)
|
struct ipc_error handle_writing_message (struct ipc_event *event, struct ipc_ctx *ctx, uint32_t index)
|
||||||
{
|
{
|
||||||
int txfd = ctx->pollfd[index].fd;
|
int txfd = ctx->pollfd[index].fd;
|
||||||
|
@ -335,19 +345,6 @@ struct ipc_error handle_new_message (struct ipc_event *event, struct ipc_ctx *ct
|
||||||
{
|
{
|
||||||
SECURE_DECLARATION (struct ipc_error, ret);
|
SECURE_DECLARATION (struct ipc_error, ret);
|
||||||
|
|
||||||
{ /* First test: should the message be switched? */
|
|
||||||
ret = fd_switching (event, ctx, index);
|
|
||||||
if (ret.error_code != IPC_ERROR_FD_SWITCHING__NO_FD_RECORD) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No treatment of the socket if external socket: the libipc user should handle it himself.
|
|
||||||
if (ctx->cinfos[index].type == IPC_CONNECTION_TYPE_EXTERNAL) {
|
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_EXTRA_SOCKET, index, ctx->pollfd[index].fd, NULL);
|
|
||||||
IPC_RETURN_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen to what they have to say (disconnection or message)
|
// Listen to what they have to say (disconnection or message)
|
||||||
// then add a client to `event`, the ipc_event structure.
|
// then add a client to `event`, the ipc_event structure.
|
||||||
struct ipc_message *m = NULL;
|
struct ipc_message *m = NULL;
|
||||||
|
@ -389,6 +386,20 @@ struct ipc_error handle_new_message (struct ipc_event *event, struct ipc_ctx *ct
|
||||||
IPC_RETURN_NO_ERROR;
|
IPC_RETURN_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ipc_error
|
||||||
|
handle_writing_switched_message (struct ipc_event *event, struct ipc_ctx *ctx, uint32_t index)
|
||||||
|
{
|
||||||
|
return fd_switching_write (event, ctx, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ipc_error
|
||||||
|
handle_switched_message(struct ipc_event *event, struct ipc_ctx *ctx, uint32_t index)
|
||||||
|
{
|
||||||
|
printf ("handling message comming from a switched fd\n");
|
||||||
|
return fd_switching_read (event, ctx, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* timer is in ms */
|
/* timer is in ms */
|
||||||
struct ipc_error ipc_wait_event (struct ipc_ctx *ctx, struct ipc_event *event, int *timer)
|
struct ipc_error ipc_wait_event (struct ipc_ctx *ctx, struct ipc_event *event, int *timer)
|
||||||
{
|
{
|
||||||
|
@ -448,12 +459,29 @@ struct ipc_error ipc_wait_event (struct ipc_ctx *ctx, struct ipc_event *event, i
|
||||||
return ipc_accept_add (event, ctx, i);
|
return ipc_accept_add (event, ctx, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fd is switched: using callbacks for IO operations.
|
||||||
|
if (ctx->cinfos[i].type == IPC_CONNECTION_TYPE_SWITCHED) {
|
||||||
|
return handle_switched_message (event, ctx, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No treatment of the socket if external socket: the libipc user should handle IO operations.
|
||||||
|
if (ctx->cinfos[i].type == IPC_CONNECTION_TYPE_EXTERNAL) {
|
||||||
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_EXTRA_SOCKET, i, ctx->pollfd[i].fd, NULL);
|
||||||
|
IPC_RETURN_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return handle_new_message (event, ctx, i);
|
return handle_new_message (event, ctx, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Something can be sent.
|
// Something can be sent.
|
||||||
if (ctx->pollfd[i].revents & POLLOUT) {
|
if (ctx->pollfd[i].revents & POLLOUT) {
|
||||||
ctx->pollfd[i].events &= ~POLLOUT;
|
ctx->pollfd[i].events &= ~POLLOUT;
|
||||||
|
|
||||||
|
// fd is switched: using callbacks for IO operations.
|
||||||
|
if (ctx->cinfos[i].type == IPC_CONNECTION_TYPE_SWITCHED) {
|
||||||
|
return handle_writing_switched_message (event, ctx, i);
|
||||||
|
}
|
||||||
|
|
||||||
return handle_writing_message (event, ctx, i);
|
return handle_writing_message (event, ctx, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
src/ipc.h
23
src/ipc.h
|
@ -216,8 +216,18 @@ struct ipc_error {
|
||||||
// with the error_message string in the ipc_error structure.
|
// with the error_message string in the ipc_error structure.
|
||||||
const char *ipc_errors_get (enum ipc_error_code e);
|
const char *ipc_errors_get (enum ipc_error_code e);
|
||||||
|
|
||||||
|
|
||||||
|
enum ipc_connection_type {
|
||||||
|
IPC_CONNECTION_TYPE_IPC = 0
|
||||||
|
, IPC_CONNECTION_TYPE_EXTERNAL = 1
|
||||||
|
/** Messages received = new connections. */
|
||||||
|
, IPC_CONNECTION_TYPE_SERVER = 2
|
||||||
|
/** IO operations should go through registered callbacks. */
|
||||||
|
, IPC_CONNECTION_TYPE_SWITCHED = 3
|
||||||
|
};
|
||||||
|
|
||||||
struct ipc_connection_info {
|
struct ipc_connection_info {
|
||||||
char type; // server, client, arbitrary fd
|
enum ipc_connection_type type;
|
||||||
char *spath; // max size: PATH_MAX
|
char *spath; // max size: PATH_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -294,12 +304,6 @@ struct ipc_event {
|
||||||
pevent->m = message_; \
|
pevent->m = message_; \
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ipc_connection_types {
|
|
||||||
IPC_CONNECTION_TYPE_IPC = 0
|
|
||||||
, IPC_CONNECTION_TYPE_EXTERNAL = 1
|
|
||||||
, IPC_CONNECTION_TYPE_SERVER = 2 /** Messages received = new connections. */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define IPC_EVENT_CLEAN(pevent) {\
|
#define IPC_EVENT_CLEAN(pevent) {\
|
||||||
pevent->type = IPC_EVENT_TYPE_NOT_SET;\
|
pevent->type = IPC_EVENT_TYPE_NOT_SET;\
|
||||||
if (pevent->m != NULL) {\
|
if (pevent->m != NULL) {\
|
||||||
|
@ -326,7 +330,8 @@ void ipc_ctx_free (struct ipc_ctx *ctx);
|
||||||
struct ipc_error ipc_read (const struct ipc_ctx *, uint32_t index, struct ipc_message *m);
|
struct ipc_error ipc_read (const struct ipc_ctx *, uint32_t index, struct ipc_message *m);
|
||||||
struct ipc_error ipc_write (struct ipc_ctx *, const struct ipc_message *m);
|
struct ipc_error ipc_write (struct ipc_ctx *, const struct ipc_message *m);
|
||||||
|
|
||||||
struct ipc_error fd_switching (struct ipc_event *event, struct ipc_ctx *ctx, int index);
|
struct ipc_error fd_switching_read (struct ipc_event *event, struct ipc_ctx *ctx, int index);
|
||||||
|
struct ipc_error fd_switching_write (struct ipc_event *event, struct ipc_ctx *ctx, int index);
|
||||||
|
|
||||||
// store and remove only pointers on allocated structures
|
// store and remove only pointers on allocated structures
|
||||||
struct ipc_error ipc_add (struct ipc_ctx *, struct ipc_connection_info *, struct pollfd *);
|
struct ipc_error ipc_add (struct ipc_ctx *, struct ipc_connection_info *, struct pollfd *);
|
||||||
|
@ -334,6 +339,8 @@ struct ipc_error ipc_del (struct ipc_ctx *, uint32_t index);
|
||||||
|
|
||||||
// add an arbitrary file descriptor to read
|
// add an arbitrary file descriptor to read
|
||||||
struct ipc_error ipc_add_fd (struct ipc_ctx *ctx, int fd);
|
struct ipc_error ipc_add_fd (struct ipc_ctx *ctx, int fd);
|
||||||
|
// add a switched file descriptor to read
|
||||||
|
struct ipc_error ipc_add_fd_switched (struct ipc_ctx *ctx, int fd);
|
||||||
struct ipc_error ipc_del_fd (struct ipc_ctx *ctx, int fd);
|
struct ipc_error ipc_del_fd (struct ipc_ctx *ctx, int fd);
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
|
|
@ -226,11 +226,11 @@ default_cb_out(int fd, struct ipc_message *m)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* switching_messages allows to send messages from a fd to another.
|
* fd_switching_read allows to read a message from a switched fd.
|
||||||
*/
|
*/
|
||||||
struct ipc_error fd_switching (struct ipc_event *event, struct ipc_ctx *ctx, int index)
|
struct ipc_error fd_switching_read (struct ipc_event *event, struct ipc_ctx *ctx, int index)
|
||||||
{
|
{
|
||||||
printf ("fd_switching\n");
|
printf ("fd_switching_read\n");
|
||||||
|
|
||||||
// If the socket is associated to another one for ipcd:
|
// If the socket is associated to another one for ipcd:
|
||||||
// read and write automatically and provide a new IPC_EVENT_TYPE indicating the switch.
|
// read and write automatically and provide a new IPC_EVENT_TYPE indicating the switch.
|
||||||
|
@ -299,3 +299,91 @@ struct ipc_error fd_switching (struct ipc_event *event, struct ipc_ctx *ctx, int
|
||||||
// 3. return IPC_ERROR_CLOSED_RECIPIENT
|
// 3. return IPC_ERROR_CLOSED_RECIPIENT
|
||||||
IPC_RETURN_ERROR (IPC_ERROR_CLOSED_RECIPIENT);
|
IPC_RETURN_ERROR (IPC_ERROR_CLOSED_RECIPIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fd_switching_write allows to read a message from a switched fd.
|
||||||
|
*/
|
||||||
|
struct ipc_error fd_switching_write (struct ipc_event *event, struct ipc_ctx *ctx, int index)
|
||||||
|
{
|
||||||
|
printf ("fd_switching_write\n");
|
||||||
|
|
||||||
|
// If the socket is associated to another one for ipcd:
|
||||||
|
// read and write automatically and provide a new IPC_EVENT_TYPE indicating the switch.
|
||||||
|
T_R ((ctx->switchdb.size == 0), IPC_ERROR_FD_SWITCHING__NO_FD_RECORD);
|
||||||
|
|
||||||
|
int output_fd = ctx->pollfd[index].fd;
|
||||||
|
struct ipc_switching sw;
|
||||||
|
struct ipc_message *m = NULL;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
// search for the next message to send for output_fd fd.
|
||||||
|
for (i = 0; ctx->tx.size ; i++) {
|
||||||
|
if (ctx->tx.messages[i].fd == output_fd) {
|
||||||
|
m = &ctx->tx.messages[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case there is no message for the fd: the error will be catched.
|
||||||
|
|
||||||
|
enum ipccb r;
|
||||||
|
int is_valid = 0;
|
||||||
|
|
||||||
|
is_valid = ipc_switching_get_ (&ctx->switchdb, output_fd, &sw);
|
||||||
|
|
||||||
|
T_R ((is_valid == -1), IPC_ERROR_FD_SWITCHING__NO_FD_RECORD);
|
||||||
|
|
||||||
|
if (sw.orig == output_fd) {
|
||||||
|
if (sw.orig_in == NULL) {
|
||||||
|
r = default_cb_out (output_fd, &m);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = (*sw.orig_out)(output_fd, &m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (sw.dest_in == NULL) {
|
||||||
|
r = default_cb_out (output_fd, &m);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = (*sw.dest_out)(output_fd, &m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Freeing the message structure.
|
||||||
|
ipc_message_empty (m);
|
||||||
|
// Removing the message from the context.
|
||||||
|
ipc_messages_del (&ctx->tx, i); // remove the message indexed by i
|
||||||
|
|
||||||
|
// Message reception OK: reading the message and put it in the list of messages to send.
|
||||||
|
if (r == IPC_CB_NO_ERROR) {
|
||||||
|
// 1. set event IPC_EVENT_TYPE_SWITCH, inform ipcd of a successful reception.
|
||||||
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_TX, index, output_fd, NULL);
|
||||||
|
// 2. IPC_RETURN_NO_ERROR
|
||||||
|
IPC_RETURN_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOTE: In any other case, the fd is, or should be closed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 1. close and remove both fd from switchdb
|
||||||
|
int delfd = ipc_switching_del (&ctx->switchdb, output_fd);
|
||||||
|
if (delfd >= 0) {
|
||||||
|
close (delfd);
|
||||||
|
ipc_del_fd (ctx, delfd);
|
||||||
|
}
|
||||||
|
close (output_fd);
|
||||||
|
ipc_del_fd (ctx, output_fd);
|
||||||
|
|
||||||
|
// 2. set event (either error or disconnection)
|
||||||
|
if (r == IPC_CB_FD_CLOSING) {
|
||||||
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_DISCONNECTION, index, output_fd, NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_ERROR, index, output_fd, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. return IPC_ERROR_CLOSED_RECIPIENT
|
||||||
|
IPC_RETURN_ERROR (IPC_ERROR_CLOSED_RECIPIENT);
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,10 @@ void ipc_ctx_print (struct ipc_ctx *ctx)
|
||||||
printf ("- external\n");
|
printf ("- external\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IPC_CONNECTION_TYPE_SWITCHED: {
|
||||||
|
printf ("- switched\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue