]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Merged from parent (trunk r11446, v3.2.0.7+).
authorAlex Rousskov <rousskov@measurement-factory.com>
Tue, 24 May 2011 22:26:21 +0000 (16:26 -0600)
committerAlex Rousskov <rousskov@measurement-factory.com>
Tue, 24 May 2011 22:26:21 +0000 (16:26 -0600)
15 files changed:
1  2 
configure.ac
include/Array.h
src/Makefile.am
src/adaptation/icap/ServiceRep.cc
src/adaptation/icap/ServiceRep.h
src/adaptation/icap/Xaction.cc
src/cache_cf.cc
src/cf.data.pre
src/client_side.cc
src/client_side_reply.cc
src/comm.cc
src/neighbors.cc
src/structs.h
src/tests/stub_store.cc
src/tools.cc

diff --cc configure.ac
Simple merge
diff --cc include/Array.h
Simple merge
diff --cc src/Makefile.am
index a69779baa88df647b11d3865d1253690bebc7405,0118aa90e82d53b11ab7081d1b2a497358907b27..38693cf1caeeea344a59290f4c892dc52abced2d
@@@ -2928,10 -2850,22 +2903,22 @@@ tests_testURL_SOURCES = 
        StoreMetaURL.cc \
        StoreMetaVary.cc \
        StoreSwapLogData.cc \
-       event.cc \
+       String.cc \
 -      SwapDir.cc \
++      SwapDir.cc MemStore.cc \
+       tests/stub_debug.cc \
+       tests/stub_DiskIOModule.cc \
+       tests/stub_main_cc.cc \
+       tests/stub_ipc_Forwarder.cc \
+       tests/testURL.cc \
+       tests/testURL.h \
+       tests/testURLScheme.cc \
+       tests/testURLScheme.h \
+       tests/testMain.cc \
+       time.cc \
        tools.cc \
        tunnel.cc \
-       SwapDir.cc MemStore.cc \
+       url.cc \
+       URLScheme.cc \
        urn.cc \
        wccp2.cc \
        whois.cc \
index 9d2f90f7434f535356f379420f1c4103bd0b7978,b5d17addb49754dc7d9f9e57252f0084d919f508..9c2edc38b564e3de50b903a3354caec41c0c5821
@@@ -72,6 -80,157 +80,161 @@@ void Adaptation::Icap::ServiceRep::note
      // should be configurable.
  }
  
 -void Adaptation::Icap::ServiceRep::putConnection(int fd, bool isReusable, const char *comment)
+ // returns a persistent or brand new connection; negative int on failures
+ int Adaptation::Icap::ServiceRep::getConnection(bool retriableXact, bool &reused)
+ {
+     Ip::Address client_addr;
+     int connection = theIdleConns.pop(cfg().host.termedBuf(), cfg().port, NULL, client_addr,
+                                       retriableXact);
+     reused = connection >= 0; // reused a persistent connection
+     if (!reused) { // need a new connection
+         Ip::Address outgoing;  // default: IP6_ANY_ADDR
+         if (!Ip::EnableIpv6)
+             outgoing.SetIPv4();
+         else if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK &&  !cfg().ipv6) {
+             /* split-stack for now requires default IPv4-only socket */
+             outgoing.SetIPv4();
+         }
+         connection = comm_open(SOCK_STREAM, 0, outgoing, COMM_NONBLOCKING, cfg().uri.termedBuf());
+     }
+     if (connection >= 0)
+         ++theBusyConns;
+     return connection;
+ }
+ // pools connection if it is reusable or closes it
 -        debugs(93, 3, HERE << "closing pconn" << comment);
++void Adaptation::Icap::ServiceRep::putConnection(int fd, bool isReusable, bool sendReset, const char *comment)
+ {
+     Must(fd >= 0);
+     // do not pool an idle connection if we owe connections
+     if (isReusable && excessConnections() == 0) {
+         debugs(93, 3, HERE << "pushing pconn" << comment);
+         commSetTimeout(fd, -1, NULL, NULL);
+         Ip::Address anyAddr;
+         theIdleConns.push(fd, cfg().host.termedBuf(), cfg().port, NULL, anyAddr);
+     } else {
 -        comm_close(fd);
++        debugs(93, 3, HERE << (sendReset ? "RST" : "FIN") << "-closing " <<
++               comment);
+         // comm_close will clear timeout
++        if (sendReset)
++            comm_reset_close(fd);
++        else
++            comm_close(fd);
+     }
+     Must(theBusyConns > 0);
+     --theBusyConns;
+     // a connection slot released. Check if there are waiters....
+     busyCheckpoint();
+ }
+ // a wrapper to avoid exposing theIdleConns
+ void Adaptation::Icap::ServiceRep::noteConnectionUse(int fd)
+ {
+     Must(fd >= 0);
+     fd_table[fd].noteUse(&theIdleConns);
+ }
+ void Adaptation::Icap::ServiceRep::setMaxConnections()
+ {
+     if (cfg().maxConn >= 0)
+         theMaxConnections = cfg().maxConn;
+     else if (theOptions && theOptions->max_connections >= 0)
+         theMaxConnections = theOptions->max_connections;
+     else {
+         theMaxConnections = -1;
+         return;
+     }
+     if (::Config.workers > 1 )
+         theMaxConnections /= ::Config.workers;
+ }
+ int Adaptation::Icap::ServiceRep::availableConnections() const
+ {
+     if (theMaxConnections < 0)
+         return -1;
+     // we are available if we can open or reuse connections
+     // in other words, if we will not create debt
+     int available = max(0, theMaxConnections - theBusyConns);
+     if (!available && !connOverloadReported) {
+         debugs(93, DBG_IMPORTANT, "WARNING: ICAP Max-Connections limit " <<
+                "exceeded for service " << cfg().uri << ". Open connections now: " <<
+                theBusyConns + theIdleConns.count() << ", including " <<
+                theIdleConns.count() << " idle persistent connections.");
+         connOverloadReported = true;
+     }
+     if (cfg().onOverload == srvForce)
+         return -1;
+     return available;
+ }
+ // The number of connections which excess the Max-Connections limit
+ int Adaptation::Icap::ServiceRep::excessConnections() const
+ {
+     if (theMaxConnections < 0)
+         return 0;
+     // Waiters affect the number of needed connections but a needed
+     // connection may still be excessive from Max-Connections p.o.v.
+     // so we should not account for waiting transaction needs here.
+     const int debt =  theBusyConns + theIdleConns.count() - theMaxConnections;
+     if (debt > 0)
+         return debt;
+     else
+         return 0;
+ }
+ void Adaptation::Icap::ServiceRep::noteGoneWaiter()
+ {
+     theAllWaiters--;
+     // in case the notified transaction did not take the connection slot
+     busyCheckpoint();
+ }
+ // called when a connection slot may become available
+ void Adaptation::Icap::ServiceRep::busyCheckpoint()
+ {
+     if (theNotificationWaiters.empty()) // nobody is waiting for a slot
+         return;
+     int freed = 0;
+     int available = availableConnections();
+     if (available < 0) {
+         // It is possible to have waiters when no limit on connections exist in
+         // case of reconfigure or because new Options received.
+         // In this case, notify all waiting transactions.
+         freed  = theNotificationWaiters.size();
+     } else {
+         // avoid notifying more waiters than there will be available slots
+         const int notifiedWaiters = theAllWaiters - theNotificationWaiters.size();
+         freed = available - notifiedWaiters;
+     }
+     debugs(93,7, HERE << "Available connections: " << available <<
+            " freed slots: " << freed <<
+            " waiting in queue: " << theNotificationWaiters.size());
+     while (freed > 0 && !theNotificationWaiters.empty()) {
+         Client i = theNotificationWaiters.front();
+         theNotificationWaiters.pop_front();
+         ScheduleCallHere(i.callback);
+         i.callback = NULL;
+         --freed;
+     }
+ }
  void Adaptation::Icap::ServiceRep::suspend(const char *reason)
  {
      if (isSuspended) {
index 30a1861e1064551eb0cad4a1bd1454ccea34e273,27caf2f24bd77002b9eea8c1984a598905608ed4..1985ced4facc091f9001a4008ad35203e1afd011
@@@ -92,10 -95,10 +95,12 @@@ public
  
      virtual void finalize();
  
 +    void invalidate(); // call when the service is no longer needed or valid
 +
      virtual bool probed() const; // see comments above
      virtual bool up() const; // see comments above
+     bool availableForNew() const; ///< a new transaction may start communicating with the service
+     bool availableForOld() const; ///< a transaction notified about connection slot availability may start communicating with the service
  
      virtual Initiate *makeXactLauncher(HttpMsg *virginHeader, HttpRequest *virginCause);
  
      bool wantsPreview(const String &urlPath, size_t &wantedSize) const;
      bool allows204() const;
      bool allows206() const;
 -    void putConnection(int fd, bool isReusable, const char *comment);
+     int getConnection(bool isRetriable, bool &isReused);
++    void putConnection(int fd, bool isReusable, bool sendReset, const char *comment);
+     void noteConnectionUse(int fd);
  
      void noteFailure(); // called by transactions to report service failure
  
index a00450ae2484d641155ff3690db03b39ca11fd42,4c39db104e0b2d57e75cc7658aa3ecbe40b57f85..dfdd45a5e48e2c6b739d33ede194ec21af5f731e
@@@ -186,25 -175,11 +175,14 @@@ void Adaptation::Icap::Xaction::closeCo
              reuseConnection = false;
          }
  
-         if (reuseConnection) {
-             Ip::Address client_addr;
-             //status() adds leading spaces.
-             debugs(93,3, HERE << "pushing pconn" << status());
-             AsyncCall::Pointer call = NULL;
-             commSetTimeout(connection, -1, call);
-             icapPconnPool->push(connection, theService->cfg().host.termedBuf(),
-                                 theService->cfg().port, NULL, client_addr);
+         if (reuseConnection)
              disableRetries();
-         } else {
-             const bool reset = al.icap.outcome == xoGone || al.icap.outcome == xoError;
-             debugs(93,3, HERE << (reset ? "RST" : "FIN") << "-closing" <<
-                    status());
-             // comm_close will clear timeout
-             if (reset)
-                 comm_reset_close(connection);
-             else
-                 comm_close(connection);
-         }
++        const bool reset = !reuseConnection &&
++            (al.icap.outcome == xoGone || al.icap.outcome == xoError);
++
+         Adaptation::Icap::ServiceRep &s = service();
 -        s.putConnection(connection, reuseConnection, status());
++        s.putConnection(connection, reuseConnection, reset, status());
  
          writer = NULL;
          reader = NULL;
diff --cc src/cache_cf.cc
Simple merge
diff --cc src/cf.data.pre
Simple merge
Simple merge
Simple merge
diff --cc src/comm.cc
Simple merge
Simple merge
diff --cc src/structs.h
Simple merge
index 9832a53f9f2114c78ebc41ac1f36b70bb40361b7,5914ed05922d8d1e8680d89a8ca026cfbd285f3c..8a186e4bffd9a488ee3e9157c7a2599a16772f7f
- /*
-  * $Id$
-  *
-  * DEBUG: section 20    Storage Manager
-  * 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.
-  *
-  */
  #include "squid.h"
- #include "Store.h"
  
- StorePointer Store::CurrentRoot = NULL;
+ #define STUB_API "store.cc"
+ #include "tests/STUB.h"
+ /* and code defined in the wrong .cc file */
+ #include "SwapDir.h"
+ void StoreController::maintain() STUB
+ #include "RemovalPolicy.h"
+ RemovalPolicy * createRemovalPolicy(RemovalPolicySettings * settings) STUB_RETVAL(NULL)
  
- extern "C" void
- storeAppendPrintf(StoreEntry * e, const char *fmt,...)
- {
-     fatal("storeAppendPrintf: Not implemented");
- }
  
- void
- storeAppendVPrintf(StoreEntry * e, const char *fmt, va_list vargs)
+ #include "Store.h"
+ StorePointer Store::CurrentRoot = NULL;
+ StoreIoStats store_io_stats;
+ bool StoreEntry::checkDeferRead(int fd) const STUB_RETVAL(false)
+ const char *StoreEntry::getMD5Text() const STUB_RETVAL(NULL)
+ StoreEntry::StoreEntry() STUB
+ StoreEntry::StoreEntry(const char *url, const char *log_url) STUB
+ HttpReply const *StoreEntry::getReply() const STUB_RETVAL(NULL)
+ void StoreEntry::write(StoreIOBuffer) STUB
+ bool StoreEntry::isAccepting() const STUB_RETVAL(false)
+ size_t StoreEntry::bytesWanted(Range<size_t> const) const STUB_RETVAL(0)
+ void StoreEntry::complete() STUB
+ store_client_t StoreEntry::storeClientType() const STUB_RETVAL(STORE_NON_CLIENT)
+ char const *StoreEntry::getSerialisedMetaData() STUB_RETVAL(NULL)
 -void StoreEntry::replaceHttpReply(HttpReply *) STUB
++void StoreEntry::replaceHttpReply(HttpReply *, bool andStartWriting) STUB
+ bool StoreEntry::swapoutPossible() STUB_RETVAL(false)
+ void StoreEntry::trimMemory() STUB
+ void StoreEntry::abort() STUB
+ void StoreEntry::unlink() STUB
+ void StoreEntry::makePublic() STUB
+ void StoreEntry::makePrivate() STUB
+ void StoreEntry::setPublicKey() STUB
+ void StoreEntry::setPrivateKey() STUB
+ void StoreEntry::expireNow() STUB
+ void StoreEntry::releaseRequest() STUB
+ void StoreEntry::negativeCache() STUB
+ void StoreEntry::cacheNegatively() STUB
+ void StoreEntry::invokeHandlers() STUB
+ void StoreEntry::purgeMem() STUB
+ void StoreEntry::swapOut() STUB
+ bool StoreEntry::swapOutAble() const STUB_RETVAL(false)
 -void StoreEntry::swapOutFileClose() STUB
++void StoreEntry::swapOutFileClose(int how) STUB
+ const char *StoreEntry::url() const STUB_RETVAL(NULL)
+ int StoreEntry::checkCachable() STUB_RETVAL(0)
+ int StoreEntry::checkNegativeHit() const STUB_RETVAL(0)
+ int StoreEntry::locked() const STUB_RETVAL(0)
+ int StoreEntry::validToSend() const STUB_RETVAL(0)
 -int StoreEntry::keepInMemory() const STUB_RETVAL(0)
++bool StoreEntry::memoryCachable() const STUB_RETVAL(false)
+ void StoreEntry::createMemObject(const char *, const char *) STUB
++void StoreEntry::hideMemObject() STUB
+ void StoreEntry::dump(int debug_lvl) const STUB
+ void StoreEntry::hashDelete() STUB
+ void StoreEntry::hashInsert(const cache_key *) STUB
+ void StoreEntry::registerAbort(STABH * cb, void *) STUB
+ void StoreEntry::reset() STUB
+ void StoreEntry::setMemStatus(mem_status_t) STUB
+ void StoreEntry::timestampsSet() STUB
+ void StoreEntry::unregisterAbort() STUB
+ void StoreEntry::destroyMemObject() STUB
+ int StoreEntry::checkTooSmall() STUB_RETVAL(0)
+ void StoreEntry::delayAwareRead(int fd, char *buf, int len, AsyncCall::Pointer callback) STUB
+ void StoreEntry::setNoDelay (bool const) STUB
+ bool StoreEntry::modifiedSince(HttpRequest * request) const STUB_RETVAL(false)
+ bool StoreEntry::hasIfMatchEtag(const HttpRequest &request) const STUB_RETVAL(false)
+ bool StoreEntry::hasIfNoneMatchEtag(const HttpRequest &request) const STUB_RETVAL(false)
 -RefCount<Store> StoreEntry::store() const STUB_RETVAL(StorePointer())
++RefCount<SwapDir> StoreEntry::store() const STUB_RETVAL(NULL)
+ size_t StoreEntry::inUseCount() STUB_RETVAL(0)
+ void StoreEntry::getPublicByRequestMethod(StoreClient * aClient, HttpRequest * request, const HttpRequestMethod& method) STUB
+ void StoreEntry::getPublicByRequest(StoreClient * aClient, HttpRequest * request) STUB
+ void StoreEntry::getPublic(StoreClient * aClient, const char *uri, const HttpRequestMethod& method) STUB
+ void *StoreEntry::operator new(size_t byteCount)
  {
-     fatal("storeAppendVPrintf: Not implemented");
+     STUB
+     return new StoreEntry();
  }
+ void StoreEntry::operator delete(void *address) STUB
+ void StoreEntry::setReleaseFlag() STUB
+ //#if USE_SQUID_ESI
+ //ESIElement::Pointer StoreEntry::cachedESITree STUB_RETVAL(NULL)
+ //#endif
+ void StoreEntry::append(char const *, int len) STUB
+ void StoreEntry::buffer() STUB
+ void StoreEntry::flush() STUB
+ int StoreEntry::unlock() STUB_RETVAL(0)
+ int64_t StoreEntry::objectLen() const STUB_RETVAL(0)
+ int64_t StoreEntry::contentLen() const STUB_RETVAL(0)
+ void StoreEntry::lock() STUB
+ void StoreEntry::release() STUB
+ NullStoreEntry *NullStoreEntry::getInstance() STUB_RETVAL(NULL)
+ const char *NullStoreEntry::getMD5Text() const STUB_RETVAL(NULL)
+ void NullStoreEntry::operator delete(void *address) STUB
+ // private virtual. Why is this linked from outside?
+ const char *NullStoreEntry::getSerialisedMetaData() STUB_RETVAL(NULL)
+ void Store::Root(Store *) STUB
+ void Store::Root(RefCount<Store>) STUB
+ void Store::Stats(StoreEntry * output) STUB
+ void Store::Maintain(void *unused) STUB
+ void Store::create() STUB
+ void Store::diskFull() STUB
+ void Store::sync() STUB
+ void Store::unlink(StoreEntry &) STUB
+ SQUIDCEXTERN size_t storeEntryInUse() STUB_RETVAL(0)
+ SQUIDCEXTERN const char *storeEntryFlags(const StoreEntry *) STUB_RETVAL(NULL)
+ void storeEntryReplaceObject(StoreEntry *, HttpReply *) STUB
+ SQUIDCEXTERN StoreEntry *storeGetPublic(const char *uri, const HttpRequestMethod& method) STUB_RETVAL(NULL)
+ SQUIDCEXTERN StoreEntry *storeGetPublicByRequest(HttpRequest * request) STUB_RETVAL(NULL)
+ SQUIDCEXTERN StoreEntry *storeGetPublicByRequestMethod(HttpRequest * request, const HttpRequestMethod& method) STUB_RETVAL(NULL)
+ SQUIDCEXTERN StoreEntry *storeCreateEntry(const char *, const char *, request_flags, const HttpRequestMethod&) STUB_RETVAL(NULL)
+ SQUIDCEXTERN void storeInit(void) STUB
+ SQUIDCEXTERN void storeConfigure(void) STUB
+ SQUIDCEXTERN void storeFreeMemory(void) STUB
+ SQUIDCEXTERN int expiresMoreThan(time_t, time_t) STUB_RETVAL(0)
+ SQUIDCEXTERN void storeAppendPrintf(StoreEntry *, const char *,...) STUB
+ void storeAppendVPrintf(StoreEntry *, const char *, va_list ap) STUB
+ SQUIDCEXTERN int storeTooManyDiskFilesOpen(void) STUB_RETVAL(0)
+ SQUIDCEXTERN void storeHeapPositionUpdate(StoreEntry *, SwapDir *) STUB
+ SQUIDCEXTERN void storeSwapFileNumberSet(StoreEntry * e, sfileno filn) STUB
+ SQUIDCEXTERN void storeFsInit(void) STUB
+ SQUIDCEXTERN void storeFsDone(void) STUB
+ SQUIDCEXTERN void storeReplAdd(const char *, REMOVALPOLICYCREATE *) STUB
+ void destroyStoreEntry(void *) STUB
+ // in Packer.cc !? SQUIDCEXTERN void packerToStoreInit(Packer * p, StoreEntry * e) STUB
+ SQUIDCEXTERN void storeGetMemSpace(int size) STUB
  
  #if !_USE_INLINE_
  #include "Store.cci"
diff --cc src/tools.cc
Simple merge