]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] stream_interface: add SI_FL_DONT_WAKE flag
authorWilly Tarreau <w@1wt.eu>
Sat, 5 Sep 2009 18:57:35 +0000 (20:57 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 23 Sep 2009 21:52:14 +0000 (23:52 +0200)
We had to add a new stream_interface flag : SI_FL_DONT_WAKE. This flag
is used to indicate that a stream interface is being updated and that
no wake up should be sent to its owner. This will be required for tasks
embedded into stream interfaces. Otherwise, we could have the
owner task send wakeups to itself during status updates, thus
preventing the state from converging. As long as a stream_interface's
status is being monitored and adjusted, there is no reason to wake it
up again, as we know its changes will be seen and considered.

include/types/stream_interface.h
src/session.c
src/stream_sock.c

index c9b0e55906f58dfe459b764a54f7cd7d251cb10e..7e997224225bf0d8fa153b7284e7cb03aeb98b61 100644 (file)
@@ -2,7 +2,7 @@
   include/types/stream_interface.h
   This file describes the stream_interface struct and associated constants.
 
-  Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
+  Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -68,6 +68,7 @@ enum {
        SI_FL_WAIT_ROOM  = 0x0004,  /* waiting for space to store incoming data */
        SI_FL_WAIT_DATA  = 0x0008,  /* waiting for more data to send */
        SI_FL_CAP_SPLTCP = 0x0010,  /* splicing possible from/to TCP */
+       SI_FL_DONT_WAKE  = 0x0020,  /* resync in progress, don't wake up */
 };
 
 #define SI_FL_CAP_SPLICE (SI_FL_CAP_SPLTCP)
index 38c14538e5917965b61ff8d1626d78ced0d7086e..d085f16ea5bfcac210442fc6c246175880d3d2b1 100644 (file)
@@ -636,6 +636,12 @@ struct task *process_session(struct task *t)
        rqf_last = s->req->flags;
        rpf_last = s->rep->flags;
 
+       /* we don't want the stream interface functions to recursively wake us up */
+       if (s->req->prod->owner == t)
+               s->req->prod->flags |= SI_FL_DONT_WAKE;
+       if (s->req->cons->owner == t)
+               s->req->cons->flags |= SI_FL_DONT_WAKE;
+
        /* 1a: Check for low level timeouts if needed. We just set a flag on
         * stream interfaces when their timeouts have expired.
         */
@@ -1128,6 +1134,10 @@ resync_stream_interface:
        if ((s->rep->flags ^ rpf_last) & BF_MASK_STATIC)
                goto resync_response;
 
+       /* we're interested in getting wakeups again */
+       s->req->prod->flags &= ~SI_FL_DONT_WAKE;
+       s->req->cons->flags &= ~SI_FL_DONT_WAKE;
+
        /* This is needed only when debugging is enabled, to indicate
         * client-side or server-side close. Please note that in the unlikely
         * event where both sides would close at once, the sequence is reported
index 72c860772947a823a2893660171b6f284adac999..ed2af6232c891fee29267bf5e6615d0a0706ccc2 100644 (file)
@@ -1087,7 +1087,8 @@ void stream_sock_chk_snd(struct stream_interface *si)
                   ((ob->flags & BF_OUT_EMPTY) && !ob->to_forward) ||
                   si->state != SI_ST_EST)) {
        out_wakeup:
-               task_wakeup(si->owner, TASK_WOKEN_IO);
+               if (!(si->flags & SI_FL_DONT_WAKE) && si->owner)
+                       task_wakeup(si->owner, TASK_WOKEN_IO);
        }
 }