]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Summary: BUGFIX: partial fix for leaking httpStateData.
authorrobertc <>
Thu, 10 Jul 2003 07:31:50 +0000 (07:31 +0000)
committerrobertc <>
Thu, 10 Jul 2003 07:31:50 +0000 (07:31 +0000)
Keywords:

* ConnectStateData was not being deleted, just freed.
* Added the (optional, but good for clarity) virtual keywords to derived methods of CommCallbackData::deleteSelf.
* Fixup test/debug LDADD - Array.o was there while testing external new and delete.
* Add a test for compiler synthetic copy operators on objects that own ones with overriden operators.

src/comm.cc
test-suite/Makefile.am
test-suite/syntheticoperators.cc [new file with mode: 0644]

index 93c0e08cefbae6c4900e7e2b8a982e0e30458f8b..18b0e636384c34272d71df3e89d4add319cb7dab 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: comm.cc,v 1.380 2003/07/06 14:16:56 hno Exp $
+ * $Id: comm.cc,v 1.381 2003/07/10 01:31:50 robertc Exp $
  *
  * DEBUG: section 5     Socket Functions
  * AUTHOR: Harvest Derived
@@ -53,6 +53,9 @@ class ConnectStateData
 {
 
 public:
+    void *operator new (size_t);
+    void operator delete (void *);
+    void deleteSelf() const;
     static void Connect (int fd, void *me);
     void connect();
     void callCallback(comm_err_t status, int xerrno);
@@ -69,6 +72,9 @@ public:
     int tries;
     int addrcount;
     int connstart;
+
+private:
+    CBDATA_CLASS(ConnectStateData);
 };
 
 /* STATIC */
@@ -87,7 +93,6 @@ static IPH commConnectDnsHandle;
 static int commResetFD(ConnectStateData * cs);
 static int commRetryConnect(ConnectStateData * cs);
 static void requireOpenAndActive(int const fd);
-CBDATA_TYPE(ConnectStateData);
 
 static PF comm_accept_try;
 
@@ -235,7 +240,7 @@ class CommReadCallbackData : public CommCallbackData
 public:
     void *operator new(size_t);
     void operator delete(void *);
-    void deleteSelf() const;
+    virtual void deleteSelf() const;
     CommReadCallbackData(CommCommonCallback const &, CallBack<IOCB> aCallback, int);
     virtual comm_callback_t getType() const { return COMM_CB_READ; }
 
@@ -253,7 +258,7 @@ class CommAcceptCallbackData : public CommCallbackData
 public:
     void *operator new(size_t);
     void operator delete(void *);
-    void deleteSelf() const;
+    virtual void deleteSelf() const;
     CommAcceptCallbackData(int const anFd, CallBack<IOACB>, comm_err_t, int, int, ConnectionDetail const &);
     virtual void callCallback();
 
@@ -270,7 +275,7 @@ class CommFillCallbackData : public CommCallbackData
 public:
     void *operator new(size_t);
     void operator delete(void *);
-    void deleteSelf() const;
+    virtual void deleteSelf() const;
     CommFillCallbackData(int const anFd, CallBack<IOFCB> aCallback, comm_err_t, int);
     virtual void callCallback();
 
@@ -285,7 +290,7 @@ class CommWriteCallbackData : public CommCallbackData
 public:
     void *operator new(size_t);
     void operator delete(void *);
-    void deleteSelf() const;
+    virtual void deleteSelf() const;
     CommWriteCallbackData(int const anFd, CallBack<IOWCB> aCallback, comm_err_t, int, int);
     virtual void callCallback();
 
@@ -1259,12 +1264,33 @@ comm_openex(int sock_type,
     return new_socket;
 }
 
+CBDATA_CLASS_INIT(ConnectStateData);
+
+void *
+ConnectStateData::operator new (size_t size)
+{
+    CBDATA_INIT_TYPE(ConnectStateData);
+    return cbdataAlloc(ConnectStateData);
+}
+
+void
+ConnectStateData::operator delete (void *address)
+{
+    cbdataFree(address);
+}
+
+void
+ConnectStateData::deleteSelf() const
+{
+    delete this;
+}
+
 void
 commConnectStart(int fd, const char *host, u_short port, CNCB * callback, void *data)
 {
     ConnectStateData *cs;
     debug(5, 3) ("commConnectStart: FD %d, data %p, %s:%d\n", fd, data, host, (int) port);
-    cs = cbdataAlloc(ConnectStateData);
+    cs = new ConnectStateData;
     cs->fd = fd;
     cs->host = xstrdup(host);
     cs->port = port;
@@ -1326,7 +1352,7 @@ commConnectFree(int fd, void *data)
     debug(5, 3) ("commConnectFree: FD %d\n", fd);
     cbdataReferenceDone(cs->callback.data);
     safe_free(cs->host);
-    cbdataFree(cs);
+    cs->deleteSelf();
 }
 
 static void
@@ -2099,8 +2125,6 @@ comm_init(void) {
      * Since Squid_MaxFD can be as high as several thousand, don't waste them */
     RESERVED_FD = XMIN(100, Squid_MaxFD / 4);
 
-    CBDATA_INIT_TYPE(ConnectStateData);
-
     comm_write_pool = memPoolCreate("CommWriteStateData", sizeof(CommWriteStateData));
 
     conn_close_pool = memPoolCreate("close_handler", sizeof(close_handler));
index 11f9cddb9db4dde85dd5b78f6e721df3db2b8c89..a1e899219e1122a7f6c81e3e0cc5e19b98415832 100644 (file)
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.am,v 1.11 2003/07/08 23:10:59 hno Exp $
+#  $Id: Makefile.am,v 1.12 2003/07/10 01:31:51 robertc Exp $
 #
 
 AUTOMAKE_OPTIONS = subdir-objects
@@ -15,6 +15,7 @@ EXTRA_PROGRAMS = mem_node_test membanger splay tcp-banger2 rfc1738
 
 ## Sort by dependencies - test lowest layers first
 TESTS = debug \
+       syntheticoperators \
        rfc1738 \
        refcount\
        splay\
@@ -31,12 +32,12 @@ check_PROGRAMS= debug \
                mem_hdr_test \
                refcount\
                rfc1738\
-               splay
+               splay \
+               syntheticoperators
 
 LDADD = -L$(top_builddir)/lib -lmiscutil
 debug_SOURCES = debug.cc test_tools.cc
-debug_LDADD = $(top_builddir)/lib/Array.o \
-               $(top_builddir)/src/globals.o \
+debug_LDADD = $(top_builddir)/src/globals.o \
                $(LDADD)
 mem_node_test_SOURCES = mem_node_test.cc
 mem_node_test_LDADD = $(top_builddir)/src/mem_node.o $(LDADD)
@@ -59,6 +60,8 @@ http_range_test_LDADD = $(top_builddir)/src/HttpHdrRange.o \
 
 splay_SOURCES = splay.cc
 
+syntheticoperators_SOURCES = syntheticoperators.cc test_tools.cc
+
 rfc1738_SOURCES = rfc1738.cc
 
 ## membanger won't link today. Bitrot..
diff --git a/test-suite/syntheticoperators.cc b/test-suite/syntheticoperators.cc
new file mode 100644 (file)
index 0000000..332df3d
--- /dev/null
@@ -0,0 +1,179 @@
+
+/*
+ * $Id: syntheticoperators.cc,v 1.1 2003/07/10 01:31:51 robertc Exp $
+ *
+ * AUTHOR: Robert Collins
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003  Robert Collins <robertc@squid-cache.org>
+ */
+
+#include "squid.h"
+#include "stmem.h"
+#include "mem_node.h"
+#include <iostream>
+
+class HasExplicit {
+  public:
+    HasExplicit();
+    ~HasExplicit();
+    HasExplicit(HasExplicit const &);
+    HasExplicit &operator=(HasExplicit const &);
+    static int const &Instances();
+    static int const &Assignments();
+    static void Assignments(int const &);
+  private:
+    static void AddInstance();
+    static void RemoveInstance();
+    static void Assignment();
+    static int Instances_;
+    static int Assignments_;
+};
+
+int HasExplicit::Instances_(0);
+int HasExplicit::Assignments_(0);
+
+HasExplicit::HasExplicit() {
+    AddInstance();
+}
+
+HasExplicit::~HasExplicit() {
+    RemoveInstance();
+}
+
+HasExplicit::HasExplicit(HasExplicit const &) {
+    AddInstance();
+}
+
+HasExplicit &
+HasExplicit::operator= (HasExplicit const &) {
+    Assignment();
+    return *this;
+}
+
+void
+HasExplicit::AddInstance()
+{
+    ++Instances_;
+}
+
+void
+HasExplicit::RemoveInstance()
+{
+    --Instances_;
+}
+
+void
+HasExplicit::Assignment()
+{
+    ++Assignments_;
+}
+
+int const &
+HasExplicit::Instances()
+{
+    return Instances_;
+}
+
+int const &
+HasExplicit::Assignments()
+{
+    return Assignments_;
+}
+
+void
+HasExplicit::Assignments(int const &newValue)
+{
+    Assignments_ = newValue;
+}
+
+void
+CheckHasExplicitWorks()
+{
+    assert (HasExplicit::Instances() == 0);
+    HasExplicit *one = new HasExplicit;
+    assert (HasExplicit::Instances() == 1);
+    HasExplicit *two = new HasExplicit;
+    assert (HasExplicit::Instances() == 2);
+    *two = *one;
+    assert (HasExplicit::Instances() == 2);
+    assert (HasExplicit::Assignments() == 1);
+    *two = *one;
+    assert (HasExplicit::Instances() == 2);
+    assert (HasExplicit::Assignments() == 2);
+    HasExplicit *three = new HasExplicit(*two);
+    assert (HasExplicit::Instances() == 3);
+    delete three;
+    assert (HasExplicit::Instances() == 2);
+    delete one;
+    assert (HasExplicit::Instances() == 1);
+    delete two;
+    assert (HasExplicit::Instances() == 0);
+    HasExplicit::Assignments(0);
+    assert (HasExplicit::Assignments() == 0);
+}
+
+class SyntheticOwnsExplicit {
+  public:
+    HasExplicit aMember;
+};
+
+void
+CheckSyntheticWorks()
+{
+    assert (HasExplicit::Instances() == 0);
+    assert (HasExplicit::Assignments() == 0);
+    SyntheticOwnsExplicit *one = new SyntheticOwnsExplicit;
+    assert (HasExplicit::Instances() == 1);
+    SyntheticOwnsExplicit *two = new SyntheticOwnsExplicit;
+    assert (HasExplicit::Instances() == 2);
+    *two = *one;
+    assert (HasExplicit::Instances() == 2);
+    assert (HasExplicit::Assignments() == 1);
+    *two = *one;
+    assert (HasExplicit::Instances() == 2);
+    assert (HasExplicit::Assignments() == 2);
+    SyntheticOwnsExplicit *three = new SyntheticOwnsExplicit(*two);
+    assert (HasExplicit::Instances() == 3);
+    delete three;
+    assert (HasExplicit::Instances() == 2);
+    delete one;
+    assert (HasExplicit::Instances() == 1);
+    delete two;
+    assert (HasExplicit::Instances() == 0);
+    HasExplicit::Assignments(0);
+    assert (HasExplicit::Assignments() == 0);
+}
+
+int
+main (int argc, char *argv)
+{
+    CheckHasExplicitWorks();
+    CheckSyntheticWorks();
+    return 0;
+}