istream-multiplex.c revision c50acc5547b9d92784825a09e3de97db0a806f4e
/* Copyright (c) 2017 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "array.h"
#include "istream-private.h"
#include "istream-multiplex.h"
/* all multiplex packets are [1 byte cid][4 byte length][data] */
struct multiplex_istream;
struct multiplex_ichannel {
struct istream_private istream;
struct multiplex_istream *mstream;
bool closed:1;
};
struct multiplex_istream {
/* channel 0 is main channel */
unsigned int remain;
bool blocking:1;
};
static struct multiplex_ichannel *
{
struct multiplex_ichannel **channelp;
return *channelp;
}
return NULL;
}
{
struct multiplex_ichannel **channelp;
}
{
struct multiplex_ichannel **channelp;
}
}
}
static ssize_t
{
const unsigned char *data;
return -1;
}
return -1;
}
return ret;
}
for(;;) {
if (len == 0) {
/* can't return 0 with blocking istreams,
so try again from the beginning. */
}
break;
}
struct multiplex_ichannel *channel =
/* is it open? */
if (!alloc_ret) {
return 0;
if (got > 0)
break;
return -2;
}
/* dump into buffer */
} else {
}
} else {
}
/* see if there is more to read */
continue;
}
/* need more data */
if (len < 5) {
if (ret > 0)
break;
}
/* channel ID */
/* data length */
}
}
return got;
}
{
/* if previous multiplex read dumped data for us
actually serve it here. */
if (channel->pending_pos > 0) {
channel->pending_pos = 0;
return ret;
}
}
static void
{
struct multiplex_ichannel *const *channelp;
if (close_parent) {
return;
}
}
{
struct multiplex_ichannel **channelp;
/* can't do anything until they are all closed */
return;
}
{
struct multiplex_ichannel **channelp;
break;
}
}
}
static struct istream *
{
if (cid == 0)
else
}
{
struct multiplex_ichannel *chan =
}
{
struct multiplex_istream *mstream;
return i_stream_add_channel_real(mstream, 0);
}
{
struct multiplex_ichannel *channel =
}