]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Summary: Prevent pushing persistent connections with outstanding writes.
authorrobertc <>
Fri, 15 Aug 2003 19:06:34 +0000 (19:06 +0000)
committerrobertc <>
Fri, 15 Aug 2003 19:06:34 +0000 (19:06 +0000)
Keywords:

Adrians' recent post to squid-dev looks like it's triggered by persistent connections being pushed inappropriately... this change adds an assert if a persistent connection is pushed while a write is outstanding.

src/comm.cc
src/comm.h
src/pconn.cc

index eb3ec33bc30a13a28c96668b92d7b7bde978adf5..3e0218503b5f808154ece2cf17663564e46f62c0 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: comm.cc,v 1.386 2003/08/04 22:14:41 robertc Exp $
+ * $Id: comm.cc,v 1.387 2003/08/15 13:06:34 robertc Exp $
  *
  * DEBUG: section 5     Socket Functions
  * AUTHOR: Harvest Derived
@@ -159,6 +159,11 @@ public:
 
     CommRead read;
 
+    bool hasIncompleteWrite();
+
+    template<class P>
+    bool findCallback(P predicate);
+
     CommWrite write;
 
     class Accept
@@ -769,14 +774,31 @@ requireOpenAndActive(int const fd)
  *
  * Assumptions: the fd is open (ie, its not closing)
  */
+
+struct FindReadCallback
+{
+    bool operator () (CommCallbackData *cd)
+    {
+        return cd->getType() == COMM_CB_READ;
+    }
+};
+
+
 int
 comm_has_pending_read_callback(int fd)
 {
-    dlink_node *node;
-    CommCallbackData *cd;
-
     requireOpenAndActive(fd);
 
+    if (fdc_table[fd].findCallback(FindReadCallback()))
+        return 1;
+
+    return 0;
+}
+
+template <class P>
+bool
+fdc_t::findCallback(P predicate)
+{
     /*
      * XXX I don't like having to walk the list!
      * Instead, if this routine is called often enough, we should
@@ -784,19 +806,17 @@ comm_has_pending_read_callback(int fd)
      * check if the list head a HEAD..
      * - adrian
      */
-    node = fdc_table[fd].CommCallbackList.head;
+    dlink_node *node = CommCallbackList.head;
 
     while (node != NULL) {
-        cd = (CommCallbackData *)node->data;
-
-        if (cd->getType() == COMM_CB_READ)
-            return 1;
+        if (predicate((CommCallbackData *)node->data))
+            return true;
 
         node = node->next;
     }
 
     /* Not found */
-    return 0;
+    return false;
 }
 
 /*
@@ -880,6 +900,32 @@ comm_udp_send(int s, const void *buf, size_t len, int flags)
 /*
  * The new-style comm_write magic
  */
+
+struct FindWriteCallback
+{
+    bool operator () (CommCallbackData *cd)
+    {
+        return dynamic_cast<CommWriteCallbackData *>(cd) != NULL;
+    }
+};
+
+bool
+comm_has_incomplete_write(int fd)
+{
+    requireOpenAndActive(fd);
+
+    if (fdc_table[fd].hasIncompleteWrite())
+        return true;
+
+    return (fdc_table[fd].findCallback(FindWriteCallback()));
+}
+
+bool
+fdc_t::hasIncompleteWrite()
+{
+    return write.handler != NULL;
+}
+
 /*
  * Attempt a write
  *
@@ -936,6 +982,9 @@ comm_write(int fd, const char *buf, size_t size, IOWCB *handler, void *handler_d
     assert(fdc_table[fd].write.handler == NULL);
     assert(!fd_table[fd].flags.closing);
 
+    /* Can't queue a write with no callback */
+    assert(handler);
+
     /* Queue a read */
     fdc_table[fd].write.buf = buf;
     fdc_table[fd].write.size = size;
index e31f0c2dcbedef6819df8ce5874b4cabc772caf4..cba1328e32c58c49766aa8d5c525e00d60590768 100644 (file)
@@ -30,6 +30,7 @@ extern void comm_accept_setcheckperiod(int fd, int mdelay);
 extern void comm_write(int s, const char *buf, size_t len, IOWCB *callback, void *callback_data);
 #include "Store.h"
 extern void commMarkHalfClosed(int);
+extern bool comm_has_incomplete_write(int);
 
 /* Where should this belong? */
 
index 54c0a8d74896c5e101408ee489ab61acf88f7bcc..3a2d9c0ebd9cf8d85659f937124edf1ebe55fb07 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: pconn.cc,v 1.39 2003/06/23 12:11:45 robertc Exp $
+ * $Id: pconn.cc,v 1.40 2003/08/15 13:06:34 robertc Exp $
  *
  * DEBUG: section 48    Persistent Connections
  * AUTHOR: Duane Wessels
@@ -282,6 +282,7 @@ pconnPush(int fd, const char *host, u_short port, const char *domain)
             xfree(old);
     }
 
+    assert(!comm_has_incomplete_write(fd));
     p->fds[p->nfds++] = fd;
     comm_read(fd, p->buf, BUFSIZ, pconnRead, p);
     commSetTimeout(fd, Config.Timeout.pconn, pconnTimeout, p);