libipc now allows buffered readings in switched context.
parent
da78f0acfd
commit
7eeda65cd9
|
@ -496,7 +496,7 @@ struct ipc_error ipc_wait_event (struct ipc_ctx *ctx, struct ipc_event *event, i
|
||||||
|
|
||||||
IPC_EVENT_CLEAN (event);
|
IPC_EVENT_CLEAN (event);
|
||||||
|
|
||||||
int32_t n;
|
int32_t n = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < ctx->size; i++) {
|
for (size_t i = 0; i < ctx->size; i++) {
|
||||||
// We assume that any fd in the list has to be listen to.
|
// We assume that any fd in the list has to be listen to.
|
||||||
|
@ -519,7 +519,18 @@ struct ipc_error ipc_wait_event (struct ipc_ctx *ctx, struct ipc_event *event, i
|
||||||
|
|
||||||
gettimeofday(&tv_1, NULL);
|
gettimeofday(&tv_1, NULL);
|
||||||
|
|
||||||
if ((n = poll(ctx->pollfd, ctx->size, *timer)) < 0) {
|
int timer_ = *timer;
|
||||||
|
|
||||||
|
/* In case there is a file descriptor that requires more to read. */
|
||||||
|
for (size_t i = 0; i <= ctx->size; i++) {
|
||||||
|
if (ctx->cinfos[i].more_to_read == 1) {
|
||||||
|
// printf ("There is more to read for _at least_ fd %d\n", ctx->pollfd[i].fd);
|
||||||
|
timer_ = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((n = poll(ctx->pollfd, ctx->size, timer_)) < 0) {
|
||||||
IPC_RETURN_ERROR (IPC_ERROR_WAIT_EVENT__POLL);
|
IPC_RETURN_ERROR (IPC_ERROR_WAIT_EVENT__POLL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,14 +549,18 @@ struct ipc_error ipc_wait_event (struct ipc_ctx *ctx, struct ipc_event *event, i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timeout.
|
// Timeout.
|
||||||
if (n == 0) {
|
if (n == 0 && timer_ != 0) {
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_TIMER, 0, 0, NULL);
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_TIMER, 0, 0, NULL);
|
||||||
IPC_RETURN_NO_ERROR;
|
IPC_RETURN_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i <= ctx->size; i++) {
|
for (size_t i = 0; i <= ctx->size; i++) {
|
||||||
// Something to read or connection.
|
// Something to read or connection.
|
||||||
if (ctx->pollfd[i].revents & POLLIN) {
|
if (ctx->pollfd[i].revents & POLLIN || ctx->cinfos[i].more_to_read == 1) {
|
||||||
|
|
||||||
|
// Avoiding loops.
|
||||||
|
ctx->cinfos[i].more_to_read = 0;
|
||||||
|
|
||||||
// In case there is something to read for the server socket: new client.
|
// In case there is something to read for the server socket: new client.
|
||||||
if (ctx->cinfos[i].type == IPC_CONNECTION_TYPE_SERVER) {
|
if (ctx->cinfos[i].type == IPC_CONNECTION_TYPE_SERVER) {
|
||||||
return ipc_accept_add (event, ctx, i);
|
return ipc_accept_add (event, ctx, i);
|
||||||
|
|
|
@ -231,6 +231,7 @@ enum ipc_connection_type {
|
||||||
|
|
||||||
struct ipc_connection_info {
|
struct ipc_connection_info {
|
||||||
enum ipc_connection_type type;
|
enum ipc_connection_type type;
|
||||||
|
short int more_to_read;
|
||||||
char *spath; // max size: PATH_MAX
|
char *spath; // max size: PATH_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -250,9 +251,9 @@ struct ipc_messages {
|
||||||
struct ipc_switching {
|
struct ipc_switching {
|
||||||
int orig;
|
int orig;
|
||||||
int dest;
|
int dest;
|
||||||
enum ipccb (*orig_in) (int origin_fd, struct ipc_message *m);
|
enum ipccb (*orig_in) (int origin_fd, struct ipc_message *m, short int *more_to_read);
|
||||||
enum ipccb (*orig_out) (int origin_fd, struct ipc_message *m);
|
enum ipccb (*orig_out) (int origin_fd, struct ipc_message *m);
|
||||||
enum ipccb (*dest_in) (int origin_fd, struct ipc_message *m);
|
enum ipccb (*dest_in) (int origin_fd, struct ipc_message *m, short int *more_to_read);
|
||||||
enum ipccb (*dest_out) (int origin_fd, struct ipc_message *m);
|
enum ipccb (*dest_out) (int origin_fd, struct ipc_message *m);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -404,11 +405,11 @@ int ipc_switching_del (struct ipc_switchings *is, int fd);
|
||||||
int ipc_switching_get (struct ipc_switchings *is, int fd);
|
int ipc_switching_get (struct ipc_switchings *is, int fd);
|
||||||
void ipc_switching_free (struct ipc_switchings *is);
|
void ipc_switching_free (struct ipc_switchings *is);
|
||||||
void ipc_switching_callbacks_ (struct ipc_ctx *ctx, int fd
|
void ipc_switching_callbacks_ (struct ipc_ctx *ctx, int fd
|
||||||
, enum ipccb (*cb_in )(int fd, struct ipc_message *m));
|
, enum ipccb (*cb_in )(int fd, struct ipc_message *m, short int *more_to_read));
|
||||||
void ipc_switching_callbacks (
|
void ipc_switching_callbacks (
|
||||||
struct ipc_ctx *ctx
|
struct ipc_ctx *ctx
|
||||||
, int fd
|
, int fd
|
||||||
, enum ipccb (*cb_in )(int fd, struct ipc_message *m)
|
, enum ipccb (*cb_in )(int fd, struct ipc_message *m, short int *more_to_read)
|
||||||
, enum ipccb (*cb_out)(int fd, struct ipc_message *m));
|
, enum ipccb (*cb_out)(int fd, struct ipc_message *m));
|
||||||
|
|
||||||
int ipc_ctx_fd_type (struct ipc_ctx *ctx, int fd, enum ipc_connection_type type);
|
int ipc_ctx_fd_type (struct ipc_ctx *ctx, int fd, enum ipc_connection_type type);
|
||||||
|
|
|
@ -197,9 +197,10 @@ void ipc_switching_free (struct ipc_switchings *is)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ipccb
|
enum ipccb
|
||||||
default_cb_in(int fd, struct ipc_message *m)
|
default_cb_in(int fd, struct ipc_message *m, short int *more_to_read)
|
||||||
{
|
{
|
||||||
// TODO: fix buffer size for switching messages
|
*more_to_read = 0;
|
||||||
|
|
||||||
size_t msize = IPC_MAX_MESSAGE_SIZE;
|
size_t msize = IPC_MAX_MESSAGE_SIZE;
|
||||||
SECURE_BUFFER_DECLARATION (char, buf, msize);
|
SECURE_BUFFER_DECLARATION (char, buf, msize);
|
||||||
char *pbuf = buf;
|
char *pbuf = buf;
|
||||||
|
@ -251,7 +252,7 @@ default_cb_out(int fd, struct ipc_message *m)
|
||||||
}
|
}
|
||||||
|
|
||||||
void ipc_switching_callbacks_ (struct ipc_ctx *ctx, int fd
|
void ipc_switching_callbacks_ (struct ipc_ctx *ctx, int fd
|
||||||
, enum ipccb (*cb_in )(int fd, struct ipc_message *m))
|
, enum ipccb (*cb_in )(int fd, struct ipc_message *m, short int *more_to_read))
|
||||||
{
|
{
|
||||||
ipc_switching_callbacks (ctx, fd, cb_in, NULL);
|
ipc_switching_callbacks (ctx, fd, cb_in, NULL);
|
||||||
}
|
}
|
||||||
|
@ -259,7 +260,7 @@ void ipc_switching_callbacks_ (struct ipc_ctx *ctx, int fd
|
||||||
void ipc_switching_callbacks (
|
void ipc_switching_callbacks (
|
||||||
struct ipc_ctx *ctx
|
struct ipc_ctx *ctx
|
||||||
, int fd
|
, int fd
|
||||||
, enum ipccb (*cb_in )(int fd, struct ipc_message *m)
|
, enum ipccb (*cb_in )(int fd, struct ipc_message *m, short int *more_to_read)
|
||||||
, enum ipccb (*cb_out)(int fd, struct ipc_message *m))
|
, enum ipccb (*cb_out)(int fd, struct ipc_message *m))
|
||||||
{
|
{
|
||||||
struct ipc_switching *sw = NULL;
|
struct ipc_switching *sw = NULL;
|
||||||
|
@ -297,6 +298,7 @@ struct ipc_error fd_switching_read (struct ipc_event *event, struct ipc_ctx *ctx
|
||||||
|
|
||||||
enum ipccb r;
|
enum ipccb r;
|
||||||
int is_valid = 0;
|
int is_valid = 0;
|
||||||
|
short int more_to_read = 0;
|
||||||
|
|
||||||
is_valid = ipc_switching_get_ (&ctx->switchdb, talkingfd, &sw);
|
is_valid = ipc_switching_get_ (&ctx->switchdb, talkingfd, &sw);
|
||||||
|
|
||||||
|
@ -305,22 +307,24 @@ struct ipc_error fd_switching_read (struct ipc_event *event, struct ipc_ctx *ctx
|
||||||
if (sw->orig == talkingfd) {
|
if (sw->orig == talkingfd) {
|
||||||
dest_fd = sw->dest;
|
dest_fd = sw->dest;
|
||||||
if (sw->orig_in == NULL) {
|
if (sw->orig_in == NULL) {
|
||||||
r = default_cb_in (talkingfd, &m);
|
r = default_cb_in (talkingfd, &m, &more_to_read);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
r = (*sw->orig_in)(talkingfd, &m);
|
r = (*sw->orig_in)(talkingfd, &m, &more_to_read);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dest_fd = sw->orig;
|
dest_fd = sw->orig;
|
||||||
if (sw->dest_in == NULL) {
|
if (sw->dest_in == NULL) {
|
||||||
r = default_cb_in (talkingfd, &m);
|
r = default_cb_in (talkingfd, &m, &more_to_read);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
r = (*sw->dest_in)(talkingfd, &m);
|
r = (*sw->dest_in)(talkingfd, &m, &more_to_read);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx->cinfos[index].more_to_read = more_to_read;
|
||||||
|
|
||||||
// Message reception OK: reading the message and put it in the list of messages to send.
|
// Message reception OK: reading the message and put it in the list of messages to send.
|
||||||
if (r == IPC_CB_NO_ERROR) {
|
if (r == IPC_CB_NO_ERROR) {
|
||||||
// In case of message reception:
|
// In case of message reception:
|
||||||
|
@ -339,7 +343,7 @@ struct ipc_error fd_switching_read (struct ipc_event *event, struct ipc_ctx *ctx
|
||||||
// This is applied to protocol-specific messages, for example when the client
|
// This is applied to protocol-specific messages, for example when the client
|
||||||
// has to communicate with the proxy, not the service.
|
// has to communicate with the proxy, not the service.
|
||||||
if (r == IPC_CB_IGNORE) {
|
if (r == IPC_CB_IGNORE) {
|
||||||
printf ("IGNORING REQUEST\n");
|
// printf ("IGNORING REQUEST\n");
|
||||||
// In case of message reception:
|
// In case of message reception:
|
||||||
// 1. set event IPC_EVENT_TYPE_SWITCH, inform ipcd of a successful reception.
|
// 1. set event IPC_EVENT_TYPE_SWITCH, inform ipcd of a successful reception.
|
||||||
IPC_EVENT_SET (event, IPC_EVENT_TYPE_SWITCH, index, ctx->pollfd[index].fd, NULL);
|
IPC_EVENT_SET (event, IPC_EVENT_TYPE_SWITCH, index, ctx->pollfd[index].fd, NULL);
|
||||||
|
|
Reference in New Issue