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_MEMOBJECT_H 10 #define SQUID_MEMOBJECT_H 11 12 #include "CommRead.h" 13 #include "dlink.h" 14 #include "http/RequestMethod.h" 15 #include "RemovalPolicy.h" 16 #include "sbuf/SBuf.h" 17 #include "SquidString.h" 18 #include "stmem.h" 19 #include "store/forward.h" 20 #include "StoreIOBuffer.h" 21 #include "StoreIOState.h" 22 #include "typedefs.h" //for IRCB 23 24 #if USE_DELAY_POOLS 25 #include "DelayId.h" 26 #endif 27 28 typedef void STMCB (void *data, StoreIOBuffer wroteBuffer); 29 typedef void STABH(void *); 30 31 class store_client; 32 class HttpRequest; 33 class HttpReply; 34 35 class MemObject 36 { 37 MEMPROXY_CLASS(MemObject); 38 39 public: 40 static size_t inUseCount(); 41 42 void dump() const; 43 MemObject(); 44 ~MemObject(); 45 46 /// Sets store ID, log URI, and request method (unless already set). Does 47 /// not clobber the method so that, say, a HEAD hit for a GET entry keeps 48 /// the GET method that matches the entry key. Same for the other parts of 49 /// the trio because the entry filling code may expect them to be constant. 50 /// XXX: Avoid this method. We plan to remove it and make the trio constant 51 /// after addressing the XXX in MemStore::get(). 52 void setUris(char const *aStoreId, char const *aLogUri, const HttpRequestMethod &aMethod); 53 54 /// whether setUris() has been called 55 bool hasUris() const; 56 57 void write(const StoreIOBuffer &buf); 58 void unlinkRequest(); 59 HttpReply const *getReply() const; 60 void replaceHttpReply(HttpReply *newrep); 61 void stat (MemBuf * mb) const; 62 int64_t endOffset () const; 63 void markEndOfReplyHeaders(); ///< sets _reply->hdr_sz to endOffset() 64 /// negative if unknown; otherwise, expected object_sz, expected endOffset 65 /// maximum, and stored reply headers+body size (all three are the same) 66 int64_t expectedReplySize() const; 67 int64_t size() const; 68 void reset(); 69 int64_t lowestMemReaderOffset() const; 70 bool readAheadPolicyCanRead() const; 71 void addClient(store_client *); 72 /* XXX belongs in MemObject::swapout, once swaphdrsz is managed 73 * better 74 */ 75 int64_t objectBytesOnDisk() const; 76 int64_t policyLowestOffsetToKeep(bool swap) const; 77 int64_t availableForSwapOut() const; ///< buffered bytes we have not swapped out yet 78 void trimSwappable(); 79 void trimUnSwappable(); 80 bool isContiguous() const; 81 int mostBytesWanted(int max, bool ignoreDelayPools) const; 82 void setNoDelay(bool const newValue); 83 #if USE_DELAY_POOLS 84 DelayId mostBytesAllowed() const; 85 #endif 86 87 #if URL_CHECKSUM_DEBUG 88 89 void checkUrlChecksum() const; 90 #endif 91 92 /// Before StoreID, code assumed that MemObject stores Request URI. 93 /// After StoreID, some old code still incorrectly assumes that. 94 /// Use this method to mark that incorrect assumption. urlXXX()95 const char *urlXXX() const { return storeId(); } 96 97 /// Entry StoreID (usually just Request URI); if a buggy code requests this 98 /// before the information is available, returns an "[unknown_URI]" string. 99 const char *storeId() const; 100 101 /// client request URI used for logging; storeId() by default 102 const char *logUri() const; 103 104 HttpRequestMethod method; 105 mem_hdr data_hdr; 106 int64_t inmem_lo = 0; 107 dlink_list clients; 108 clientCount()109 size_t clientCount() const {return nclients;} 110 clientIsFirst(void * sc)111 bool clientIsFirst(void *sc) const {return (clients.head && sc == clients.head->data);} 112 113 int nclients = 0; 114 115 class SwapOut 116 { 117 public: 118 int64_t queue_offset = 0; ///< number of bytes sent to SwapDir for writing 119 StoreIOState::Pointer sio; 120 121 /// Decision states for StoreEntry::swapoutPossible() and related code. 122 typedef enum { swNeedsCheck = 0, swImpossible = -1, swPossible = +1, swStarted } Decision; 123 Decision decision = swNeedsCheck; ///< current decision state 124 }; 125 126 SwapOut swapout; 127 128 /* TODO: Remove this change-minimizing hack */ 129 using Io = Store::IoStatus; 130 static constexpr Io ioUndecided = Store::ioUndecided; 131 static constexpr Io ioReading = Store::ioReading; 132 static constexpr Io ioWriting = Store::ioWriting; 133 static constexpr Io ioDone = Store::ioDone; 134 135 /// State of an entry with regards to the [shared] in-transit table. 136 class XitTable 137 { 138 public: 139 int32_t index = -1; ///< entry position inside the in-transit table 140 Io io = ioUndecided; ///< current I/O state 141 }; 142 XitTable xitTable; ///< current [shared] memory caching state for the entry 143 144 /// State of an entry with regards to the [shared] memory caching. 145 class MemCache 146 { 147 public: 148 int32_t index = -1; ///< entry position inside the memory cache 149 int64_t offset = 0; ///< bytes written/read to/from the memory cache so far 150 151 Io io = ioUndecided; ///< current I/O state 152 }; 153 MemCache memCache; ///< current [shared] memory caching state for the entry 154 155 /* Read only - this reply must be preserved by store clients */ 156 /* The original reply. possibly with updated metadata. */ 157 HttpRequest *request = nullptr; 158 159 struct timeval start_ping; 160 IRCB *ping_reply_callback; 161 void *ircb_data = nullptr; 162 163 struct abort_ { abort_abort_164 abort_() { callback = nullptr; } 165 STABH *callback; 166 void *data = nullptr; 167 } abort; 168 RemovalPolicyNode repl; 169 int id = 0; 170 int64_t object_sz = -1; 171 size_t swap_hdr_sz = 0; 172 #if URL_CHECKSUM_DEBUG 173 unsigned int chksum = 0; 174 #endif 175 176 SBuf vary_headers; 177 178 void delayRead(DeferredRead const &); 179 void kickReads(); 180 181 private: 182 HttpReply *_reply = nullptr; 183 184 mutable String storeId_; ///< StoreId for our entry (usually request URI) 185 mutable String logUri_; ///< URI used for logging (usually request URI) 186 187 DeferredReadManager deferredReads; 188 }; 189 190 /** global current memory removal policy */ 191 extern RemovalPolicy *mem_policy; 192 193 #endif /* SQUID_MEMOBJECT_H */ 194 195