]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: iostream-proxy - Specify what failed in completion callback parameter
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Sun, 29 Oct 2017 22:30:13 +0000 (00:30 +0200)
committerTimo Sirainen <tss@dovecot.fi>
Wed, 1 Nov 2017 00:23:31 +0000 (02:23 +0200)
src/lib/iostream-proxy.c
src/lib/iostream-proxy.h
src/lib/test-iostream-proxy.c

index ca74b0d5bcdfeabf83a611116b5f5ffbf80131ad..97971d62f16b9d5e14d872bdf8583cd9756e522d 100644 (file)
@@ -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 *
index 6b290a6f2921119125da817d90208a5d4df4a142..dfb1b3e748ad72a1628f25d58c652af87a680eaf 100644 (file)
@@ -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 *
@@ -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);
index c2666b43e3af25f92b17d82eb741028e25abd45a..ff0a4ebd0566a2177f51d2d4545db71c654d6d3d 100644 (file)
@@ -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)