1 /* 2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors 3 * 4 * Squid software is distributed under GPLv2+ license and includes 5 * contributions from numerous individuals and organizations. 6 * Please see the COPYING and CONTRIBUTORS files for details. 7 */ 8 9 #ifndef SQUID_PCONN_H 10 #define SQUID_PCONN_H 11 12 #include "base/CbcPointer.h" 13 #include "base/RunnersRegistry.h" 14 #include "mgr/forward.h" 15 16 #include <set> 17 18 /** 19 \defgroup PConnAPI Persistent Connection API 20 \ingroup Component 21 * 22 \todo CLEANUP: Break multiple classes out of the generic pconn.h header 23 */ 24 25 class PconnPool; 26 class PeerPoolMgr; 27 28 #include "cbdata.h" 29 #include "hash.h" 30 /* for IOCB */ 31 #include "comm.h" 32 33 /// \ingroup PConnAPI 34 #define PCONN_HIST_SZ (1<<16) 35 36 /** \ingroup PConnAPI 37 * A list of connections currently open to a particular destination end-point. 38 */ 39 class IdleConnList: public hash_link, private IndependentRunner 40 { 41 CBDATA_CLASS(IdleConnList); 42 43 public: 44 IdleConnList(const char *key, PconnPool *parent); 45 ~IdleConnList(); 46 47 /// Pass control of the connection to the idle list. 48 void push(const Comm::ConnectionPointer &conn); 49 50 /// get first conn which is not pending read fd. 51 Comm::ConnectionPointer pop(); 52 53 /** Search the list for a connection which matches the 'key' details 54 * and pop it off the list. 55 * The list is created based on remote IP:port hash. This further filters 56 * the choices based on specific local-end details requested. 57 * If nothing usable is found the a nil pointer is returned. 58 */ 59 Comm::ConnectionPointer findUseable(const Comm::ConnectionPointer &key); 60 61 void clearHandlers(const Comm::ConnectionPointer &conn); 62 count()63 int count() const { return size_; } 64 void closeN(size_t count); 65 66 // IndependentRunner API 67 virtual void endingShutdown(); 68 private: 69 bool isAvailable(int i) const; 70 bool removeAt(int index); 71 int findIndexOf(const Comm::ConnectionPointer &conn) const; 72 void findAndClose(const Comm::ConnectionPointer &conn); 73 static IOCB Read; 74 static CTCB Timeout; 75 76 private: 77 /** List of connections we are holding. 78 * Sorted as FIFO list for most efficient speeds on pop() and findUsable() 79 * The worst-case pop() and scans occur on timeout and link closure events 80 * where timing is less critical. Occasional slow additions are okay. 81 */ 82 Comm::ConnectionPointer *theList_; 83 84 /// Number of entries theList can currently hold without re-allocating (capacity). 85 int capacity_; 86 ///< Number of in-use entries in theList 87 int size_; 88 89 /** The pool containing this sub-list. 90 * The parent performs all stats accounting, and 91 * will delete us when it dies. It persists for the 92 * full duration of our existence. 93 */ 94 PconnPool *parent_; 95 96 char fakeReadBuf_[4096]; // TODO: kill magic number. 97 }; 98 99 #include "ip/forward.h" 100 101 class StoreEntry; 102 class IdleConnLimit; 103 104 /* for hash_table */ 105 #include "hash.h" 106 107 /** \ingroup PConnAPI 108 * Manages idle persistent connections to a caller-defined set of 109 * servers (e.g., all HTTP servers). Uses a collection of IdleConnLists 110 * internally to list the individual open connections to each server. 111 * Controls lists existence and limits the total number of 112 * idle connections across the collection. 113 */ 114 class PconnPool 115 { 116 117 public: 118 PconnPool(const char *aDescription, const CbcPointer<PeerPoolMgr> &aMgr); 119 ~PconnPool(); 120 121 void moduleInit(); 122 void push(const Comm::ConnectionPointer &serverConn, const char *domain); 123 124 /** 125 * Returns either a pointer to a popped connection to dest or nil. 126 * Closes the connection before returning its pointer unless keepOpen. 127 * 128 * A caller with a non-retriable transaction should set keepOpen to false 129 * and call pop() anyway, even though the caller does not want a pconn. 130 * This forces us to close an available persistent connection, avoiding 131 * creating a growing number of open connections when many transactions 132 * create (and push) persistent connections but are not retriable and, 133 * hence, do not need to pop a connection. 134 */ 135 Comm::ConnectionPointer pop(const Comm::ConnectionPointer &dest, const char *domain, bool keepOpen); 136 void count(int uses); 137 void dumpHist(StoreEntry *e) const; 138 void dumpHash(StoreEntry *e) const; 139 void unlinkList(IdleConnList *list); 140 void noteUses(int uses); 141 /// closes any n connections, regardless of their destination 142 void closeN(int n); count()143 int count() const { return theCount; } noteConnectionAdded()144 void noteConnectionAdded() { ++theCount; } noteConnectionRemoved()145 void noteConnectionRemoved() { assert(theCount > 0); --theCount; } 146 147 // sends an async message to the pool manager, if any 148 void notifyManager(const char *reason); 149 150 private: 151 152 static const char *key(const Comm::ConnectionPointer &destLink, const char *domain); 153 154 int hist[PCONN_HIST_SZ]; 155 hash_table *table; 156 const char *descr; 157 CbcPointer<PeerPoolMgr> mgr; ///< optional pool manager (for notifications) 158 int theCount; ///< the number of pooled connections 159 }; 160 161 class StoreEntry; 162 class PconnPool; 163 164 /** \ingroup PConnAPI 165 * The global registry of persistent connection pools. 166 */ 167 class PconnModule 168 { 169 170 public: 171 /** the module is a singleton until we have instance based cachemanager 172 * management 173 */ 174 static PconnModule * GetInstance(); 175 /** A thunk to the still C like CacheManager callback api. */ 176 static void DumpWrapper(StoreEntry *e); 177 178 PconnModule(); 179 void registerWithCacheManager(void); 180 181 void add(PconnPool *); 182 void remove(PconnPool *); ///< unregister and forget about this pool object 183 184 OBJH dump; 185 186 private: 187 typedef std::set<PconnPool*> Pools; ///< unordered PconnPool collection 188 Pools pools; ///< all live pools 189 190 static PconnModule * instance; 191 }; 192 193 #endif /* SQUID_PCONN_H */ 194 195