From: robertc <> Date: Thu, 10 Jul 2003 07:31:50 +0000 (+0000) Subject: Summary: BUGFIX: partial fix for leaking httpStateData. X-Git-Tag: SQUID_3_0_PRE1~48 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d2d59a685e49ce318330b91c3a1b1352fa30b895;p=thirdparty%2Fsquid.git Summary: BUGFIX: partial fix for leaking httpStateData. 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. --- diff --git a/src/comm.cc b/src/comm.cc index 93c0e08cef..18b0e63638 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -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 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, 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 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 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)); diff --git a/test-suite/Makefile.am b/test-suite/Makefile.am index 11f9cddb9d..a1e899219e 100644 --- a/test-suite/Makefile.am +++ b/test-suite/Makefile.am @@ -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 index 0000000000..332df3d7d4 --- /dev/null +++ b/test-suite/syntheticoperators.cc @@ -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 + */ + +#include "squid.h" +#include "stmem.h" +#include "mem_node.h" +#include + +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; +}