]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stream-int: add two flags to indicate an applet's wishes regarding I/O
authorWilly Tarreau <w@1wt.eu>
Tue, 21 Apr 2015 16:44:02 +0000 (18:44 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 23 Apr 2015 15:56:17 +0000 (17:56 +0200)
Currently we have a problem. There are some cases where a sleeping applet
is not woken up (eg: show sess during an injection). The reason is that
the applet is marked WAIT_DATA and is not woken up when WAIT_ROOM leaves,
because we wait for both flags to be cleared in order to call it.

And if we wait for either flag, then we have the opposite situation, which
is that we're not waiting for room in the output buffer so we're spinning
calling the applet to do nothing.

What is missing is an indication of what the applet needs. Since it only
manipulates the WAIT_ROOM/WAIT_DATA which are overwritten later, that cannot
work. In the case of connections, the problem doesn't happen because the
connection maintains these extra states. Ideally we'd need to have similar
states for each appctx and to store those information there. But it would
be overcomplicated given that an applet doesn't exist alone without a
stream-int, so we can safely put these information into the stream int and
make the code simpler.

With this patch we introduce two new flags in the stream interface :
  - SI_FL_WANT_PUT : the applet wants to put something into the buffer
  - SI_FL_WANT_GET : the applet wants to get something from the buffer

We also have the new functions si_applet_{stop|want|cant}_{get|put}
to make the code look similar to the connection code.

For now these flags are not used yet.

include/proto/stream_interface.h
include/types/stream_interface.h

index a6f6d33e0eb088edbb8c04fae64ffa7543657ebe..7f543242d3b303fc9e8df034ded9986ae62be5a3 100644 (file)
@@ -236,6 +236,46 @@ static inline void si_applet_release(struct stream_interface *si)
                appctx->applet->release(appctx);
 }
 
+/* let an applet indicate that it wants to put some data into the input buffer */
+static inline void si_applet_want_put(struct stream_interface *si)
+{
+       si->flags |= SI_FL_WANT_PUT;
+}
+
+/* let an applet indicate that it wanted to put some data into the input buffer
+ * but it couldn't.
+ */
+static inline void si_applet_cant_put(struct stream_interface *si)
+{
+       si->flags |= SI_FL_WANT_PUT | SI_FL_WAIT_ROOM;
+}
+
+/* let an applet indicate that it doesn't want to put data into the input buffer */
+static inline void si_applet_stop_put(struct stream_interface *si)
+{
+       si->flags &= ~SI_FL_WANT_PUT;
+}
+
+/* let an applet indicate that it wants to get some data from the output buffer */
+static inline void si_applet_want_get(struct stream_interface *si)
+{
+       si->flags |= SI_FL_WANT_GET;
+}
+
+/* let an applet indicate that it wanted to get some data from the output buffer
+ * but it couldn't.
+ */
+static inline void si_applet_cant_get(struct stream_interface *si)
+{
+       si->flags |= SI_FL_WANT_GET | SI_FL_WAIT_DATA;
+}
+
+/* let an applet indicate that it doesn't want to get data from the input buffer */
+static inline void si_applet_stop_get(struct stream_interface *si)
+{
+       si->flags &= ~SI_FL_WANT_GET;
+}
+
 /* Try to allocate a new connection and assign it to the interface. If
  * a connection was previously allocated and the <reuse> flag is set,
  * it is returned unmodified. Otherwise it is reset.
index 9b228e57c83186b6d7c34d0ea468e9ef19f557fd..51bb4d61a88f01bc1c3e51983b29b4950964be07 100644 (file)
@@ -72,6 +72,8 @@ enum {
        SI_FL_NOLINGER   = 0x0080,  /* may close without lingering. One-shot. */
        SI_FL_NOHALF     = 0x0100,  /* no half close, close both sides at once */
        SI_FL_SRC_ADDR   = 0x1000,  /* get the source ip/port with getsockname */
+       SI_FL_WANT_PUT   = 0x2000,  /* an applet would like to put some data into the buffer */
+       SI_FL_WANT_GET   = 0x4000,  /* an applet would like to get some data from the buffer */
 };
 
 /* A stream interface has 3 parts :