Skip to content

Commit

Permalink
lib: iostream-proxy - Specify what failed in completion callback para…
Browse files Browse the repository at this point in the history
…meter
  • Loading branch information
sirainen authored and Timo Sirainen committed Nov 1, 2017
1 parent 39435f0 commit 987c15a
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 7 deletions.
29 changes: 25 additions & 4 deletions src/lib/iostream-proxy.c
Expand Up @@ -19,20 +19,41 @@ struct iostream_proxy {
void *context;
};

static void
iostream_proxy_completion(struct iostream_proxy *proxy,
enum iostream_proxy_side side,
enum iostream_pump_status pump_status)
{
enum iostream_proxy_status status;

switch (pump_status) {
case IOSTREAM_PUMP_STATUS_INPUT_EOF:
status = IOSTREAM_PROXY_STATUS_INPUT_EOF;
break;
case IOSTREAM_PUMP_STATUS_INPUT_ERROR:
status = IOSTREAM_PROXY_STATUS_INPUT_ERROR;
break;
case IOSTREAM_PUMP_STATUS_OUTPUT_ERROR:
status = IOSTREAM_PROXY_STATUS_OTHER_SIDE_OUTPUT_ERROR;
break;
default:
i_unreached();
}
proxy->callback(side, status, proxy->context);
}

static
void iostream_proxy_rtl_completion(enum iostream_pump_status status,
struct iostream_proxy *proxy)
{
bool success = (status == IOSTREAM_PUMP_STATUS_INPUT_EOF);
proxy->callback(IOSTREAM_PROXY_SIDE_RIGHT, success, proxy->context);
iostream_proxy_completion(proxy, IOSTREAM_PROXY_SIDE_RIGHT, status);
}

static
void iostream_proxy_ltr_completion(enum iostream_pump_status status,
struct iostream_proxy *proxy)
{
bool success = (status == IOSTREAM_PUMP_STATUS_INPUT_EOF);
proxy->callback(IOSTREAM_PROXY_SIDE_LEFT, success, proxy->context);
iostream_proxy_completion(proxy, IOSTREAM_PROXY_SIDE_LEFT, status);
}

struct iostream_proxy *
Expand Down
28 changes: 26 additions & 2 deletions src/lib/iostream-proxy.h
Expand Up @@ -26,12 +26,36 @@ struct ostream;
struct iostream_proxy;

enum iostream_proxy_side {
/* Input is coming from left side's istream and is proxied to
right side's ostream. */
IOSTREAM_PROXY_SIDE_LEFT,
/* Input is coming from right side's istream and is proxied to
left side's ostream. */
IOSTREAM_PROXY_SIDE_RIGHT
};

enum iostream_proxy_status {
/* proxy succeeded - EOF received from istream and all output was
written successfully to ostream. */
IOSTREAM_PROXY_STATUS_INPUT_EOF,
/* proxy failed - istream returned an error */
IOSTREAM_PROXY_STATUS_INPUT_ERROR,
/* proxy failed - other side's ostream returned an error */
IOSTREAM_PROXY_STATUS_OTHER_SIDE_OUTPUT_ERROR,
};

/* The callback maybe be called once or twice. Usually the first call should
destroy the proxy, but it's possible for it to just wait for the other
direction of the proxy to finish as well and call the callback.
Note that the sides mean which side is the reader side. If the failure is in
ostream, it's the other side's ostream that failed. So for example if
side=left, the write failed to the right side's ostream.
The callback is called when the proxy succeeds or fails due to
iostreams. (It's not called if proxy is destroyed.) */
typedef void iostream_proxy_callback_t(enum iostream_proxy_side side,
bool success,
enum iostream_proxy_status status,
void *context);

struct iostream_proxy *
Expand All @@ -52,7 +76,7 @@ void iostream_proxy_set_completion_callback(struct iostream_proxy *proxy,
iostream_proxy_callback_t *callback, void *context);
#define iostream_proxy_set_completion_callback(proxy, callback, context) \
iostream_proxy_set_completion_callback(proxy, (iostream_proxy_callback_t *)callback, context + \
CALLBACK_TYPECHECK(callback, void (*)(enum iostream_proxy_side side, bool, typeof(context))))
CALLBACK_TYPECHECK(callback, void (*)(enum iostream_proxy_side side, enum iostream_proxy_status, typeof(context))))

void iostream_proxy_ref(struct iostream_proxy *proxy);
void iostream_proxy_unref(struct iostream_proxy **proxy_r);
Expand Down
3 changes: 2 additions & 1 deletion src/lib/test-iostream-proxy.c
Expand Up @@ -12,7 +12,8 @@
#include <sys/socket.h>

static
void completed(enum iostream_proxy_side side ATTR_UNUSED, bool success ATTR_UNUSED, int *u0)
void completed(enum iostream_proxy_side side ATTR_UNUSED,
enum iostream_proxy_status status ATTR_UNUSED, int *u0)
{
i_assert(*u0 > 0);
if (--*u0 == 0)
Expand Down

0 comments on commit 987c15a

Please sign in to comment.