77 if (doingRevalidation)
78 tags->collapsingHistory.revalidationCollapses++;
80 tags->collapsingHistory.otherCollapses++;
84 debugs(85, 5, e <<
" doingRevalidation=" << doingRevalidation);
96#if STORE_CLIENT_LIST_DEBUG
98storeClientListSearch(
const MemObject * mem,
void *data)
106 if (sc->owner == data)
116 return sc->owner == someClient;
129#if STORE_CLIENT_LIST_DEBUG
131 if (storeClientListSearch(mem, data) !=
NULL)
189 temphandler(
cbdata, result);
193#if STORE_CLIENT_LIST_DEBUG
197 type(e->storeClientType()),
205 flags.disk_io_pending =
false;
206 flags.store_copying =
false;
231 sc->
copy(e, copyInto,callback,data);
245 copyRequest.
offset <<
", for length " <<
246 (
int) copyRequest.
length <<
", cb " << callback_fn <<
", cbdata " <<
249#if STORE_CLIENT_LIST_DEBUG
266 debugs(90, 2,
"WARNING: zero-size storeClientCopy() buffer: " <<
copyInto);
282 static bool copying (
false);
291 anEntry->
lock(
"store_client::copy");
301 anEntry->
unlock(
"store_client::copy");
340 debugs(90, 3,
"prevented recursive copying for " << *e);
372 flags.store_copying =
true;
384 debugs(33, 3,
"There is no more to send!");
386 flags.store_copying =
false;
391 debugs(90, 3,
"store_client::doCopy: Waiting for more");
392 flags.store_copying =
false;
418 flags.store_copying =
false;
422 if (sendHttpHeaders) {
425 flags.store_copying =
false;
437 debugs(90, 3,
"store_client::doCopy: Need to open swap in file");
443 flags.store_copying =
false;
445 }
else if (!
flags.disk_io_pending) {
451 flags.store_copying =
false;
458 flags.store_copying =
false;
481 debugs(90, 3,
"bailing after swapin start failure for " << *
entry);
488 debugs(90, 3,
"reading " << *
entry <<
" from disk");
492 flags.store_copying =
false;
530 debugs(90, 3,
"copying HTTP body bytes from memory into " << readInto);
543 flags.disk_io_pending =
true;
589 flags.disk_io_pending =
false;
594 if (lastIoResult < 0)
697 debugs(90, 5,
"client lost interest");
732 flags.disk_io_pending =
false;
768#if STORE_CLIENT_LIST_DEBUG
780 debugs(90, 3,
"storeUnregister: No matching client for '" << e->
getMD5Text() <<
"'");
785 debugs(90, 3,
"storeUnregister: Consistency failure - store client being unregistered is not in the mem object's list for '" << e->
getMD5Text() <<
"'");
803 debugs(90, 3,
"forgetting store_client callback for " << *e);
810#if STORE_CLIENT_LIST_DEBUG
817 e->
lock(
"storeUnregister");
832 e->
unlock(
"storeUnregister");
841 debugs(90, 3,
"DELAY_SENDING is on, exiting " << *
this);
845 debugs(90, 3,
"ENTRY_FWD_HDR_WAIT is on, exiting " << *
this);
882 debugs(90, 3,
"checking client #" << i);
893 int npend =
nullptr == mem ? 0 : mem->
nclients;
894 debugs(90, 3,
"storePendingNClients: returning " << npend);
903 debugs(90, 3,
"entry=" << *entry);
906 debugs(90, 3,
"quick-abort? NO storePendingNClients() > 0");
911 debugs(90, 3,
"quick-abort? NO still have one or more transient readers");
916 debugs(90, 3,
"quick-abort? NO store_status != STORE_PENDING");
921 debugs(90, 3,
"quick-abort? NO ENTRY_SPECIAL");
926 debugs(90, 3,
"quick-abort? YES avoid heavy optional work during shutdown");
932 debugs(90, 3,
"mem=" << mem);
935 debugs(90, 3,
"quick-abort? YES !mem->request->flags.cachable");
940 debugs(90, 3,
"quick-abort? YES KEY_PRIVATE");
946 if (reply.hdr_sz <= 0) {
948 debugs(90, 3,
"quick-abort? YES no object data received yet");
953 debugs(90, 3,
"quick-abort? NO disabled");
959 debugs(90, 3,
"quick-abort? NO admin configured range replies to full-download");
963 if (reply.content_length < 0) {
966 debugs(90, 3,
"quick-abort? YES unknown content length");
969 const auto expectlen = reply.hdr_sz + reply.content_length;
973 if (curlen > expectlen) {
974 debugs(90, 3,
"quick-abort? YES bad content length (" << curlen <<
" of " << expectlen <<
" bytes received)");
979 debugs(90, 3,
"quick-abort? NO only a little more object left to receive");
984 debugs(90, 3,
"quick-abort? YES too much left to go");
989 debugs(90, 3,
"quick-abort? NO past point of no return");
993 debugs(90, 3,
"quick-abort? YES default");
1044 debugs(90, 5,
"discovered " << hdr_sz <<
"-byte HTTP headers in memory after reading some of them from disk: " << *
parsingBuffer);
1048 const auto httpBodyBytesAfterHeader =
parsingBuffer->contentSize();
1050 debugs(90, 5,
"read HTTP body prefix: " << httpBodyBytesAfterHeader);
1060 output->
appendf(
"\tClient #%d, %p\n", clientNumber,
this);
1063 output->
append(
"\t\tflags:", 8);
1065 if (
flags.disk_io_pending)
1066 output->
append(
" disk_io_pending", 16);
1068 if (
flags.store_copying)
1069 output->
append(
" store_copying", 14);
1072 output->
append(
" notifying", 10);
1084 callback_handler(function),
#define Assure(condition)
#define ScheduleCallHere(call)
RefCount< AsyncCallT< Dialer > > asyncCall(int aDebugSection, int aDebugLevel, const char *aName, const Dialer &aDialer)
UnaryCbdataDialer< Argument1 > cbdataDialer(typename UnaryCbdataDialer< Argument1 >::Handler *handler, Argument1 *arg1)
constexpr bool Less(const A a, const B b)
whether integer a is less than integer b, with correct overflow handling
void(void *, StoreIOBuffer) STCB
int storeClientIsThisAClient(store_client *sc, void *someClient)
std::ostream & CurrentException(std::ostream &os)
prints active (i.e., thrown but not yet handled) exception
void error(char *format,...)
#define cbdataReferenceDone(var)
#define cbdataReference(var)
#define CBDATA_CLASS_INIT(type)
Acl::Answer const & fastCheck()
virtual void fillChecklist(ACLFilledChecklist &) const =0
configure the given checklist (to reflect the current transaction state)
bool cancel(const char *reason)
static const Pointer & Current()
static void Reset()
forgets the current context, setting it to nil/unknown
static std::ostream & Extra(std::ostream &)
int bytesWanted(int min, int max) const
int64_t getRangeOffsetLimit()
void append(const char *c, int sz) override
StoreIOState::Pointer sio
size_t clientCount() const
HttpRequestPointer request
void addClient(store_client *)
void write(const StoreIOBuffer &buf)
int64_t endOffset() const
const HttpReply & baseReply() const
HttpReply & adjustableBaseReply()
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
SupportOrVeto cachable
whether the response may be stored in the cache
struct SquidConfig::@76 quickAbort
acl_access * collapsedForwardingAccess
struct SquidConfig::@90 onoff
struct SquidConfig::@91 accessList
struct SquidConfig::@88 Store
struct StatCounters::@113 swap
bool onCollapsingPath() const
whether Squid configuration allows collapsing for this transaction
bool didCollapse
whether startCollapsingOn() was called and returned true
virtual LogTags * loggingTags() const =0
bool startCollapsingOn(const StoreEntry &, const bool doingRevalidation) const
bool swappedOut() const
whether the entire entry is now on disk (possibly marked for deletion)
int unlock(const char *context)
bool hasDisk(const sdirno dirn=-1, const sfileno filen=-1) const
bool hasParsedReplyHeader() const
whether this entry has access to [deserialized] [HTTP] response headers
void lock(const char *context)
bool swappingOut() const
whether we are in the process of writing this entry to disk
const char * getMD5Text() const
void kickProducer()
calls back producer registered with deferProducer
int64_t objectLen() const
store_status_t store_status
int64_t contentLen() const
bool swapoutFailed() const
whether we failed to write this entry to disk
bool hittingRequiresCollapsing() const
whether this entry can feed collapsed requests and only them
StoreIOBuffer & positionAt(const int64_t newOffset)
convenience method for changing the offset of a being-configured buffer
@ readerDone
success or failure: either way, stop swapping in
void STRCB(void *their_data, const char *buf, ssize_t len, StoreIOState::Pointer self)
ssize_t copy(StoreIOBuffer const &) const
bool sendingHttpHeaders() const
void readHeader(const char *buf, ssize_t len)
void skipHttpHeadersFromDisk()
skips HTTP header bytes previously loaded from disk
void handleBodyFromDisk()
de-serializes HTTP response (partially) read from disk storage
void setDelayId(DelayId delay_id)
std::optional< Store::ParsingBuffer > parsingBuffer
bool startSwapin()
opens the swapin "file" if possible; otherwise, fail()s and returns false
bool answeredOnce() const
void noteNews()
if necessary and possible, informs the Store reader about copy() result
bool parseHttpHeadersFromDisk()
bool moreToRead() const
Whether Store has (or possibly will have) more entry data for us.
void noteSwapInDone(bool error)
int64_t discardableHttpEnd_
the client will not use HTTP response bytes with lower offsets (if any)
StoreIOBuffer lastDiskRead
buffer used for the last storeRead() call
void readBody(const char *buf, ssize_t len)
int64_t nextHttpReadOffset() const
The offset of the next stored HTTP response byte wanted by the client.
struct store_client::@122 flags
void copy(StoreEntry *, StoreIOBuffer, STCB *, void *)
bool tryParsingHttpHeaders()
void doCopy(StoreEntry *e)
void maybeWriteFromDiskToMemory(const StoreIOBuffer &)
bool canReadFromMemory() const
whether at least one byte wanted by the client is in memory
struct store_client::Callback _callback
void finishCallback()
finishes a copy()-STCB sequence by synchronously calling STCB
store_client(StoreEntry *)
static void FinishCallback(store_client *)
finishCallback() wrapper; TODO: Add NullaryMemFunT for non-jobs.
uint64_t answers
the total number of finishCallback() calls
StoreIOState::Pointer swapin_sio
void dumpStats(MemBuf *output, int clientNumber) const
#define debugs(SECTION, LEVEL, CONTENT)
#define EBIT_TEST(flag, bit)
void dlinkDelete(dlink_node *m, dlink_list *list)
Controller & Root()
safely access controller singleton
void UnpackHitSwapMeta(char const *, ssize_t, StoreEntry &)
deserializes entry metadata from the given buffer into the cache hit entry
void storeGetMemSpace(int size)
int storeTooManyDiskFilesOpen(void)
int storeUnregister(store_client *sc, StoreEntry *e, void *data)
void storeClientCopy(store_client *sc, StoreEntry *e, StoreIOBuffer copyInto, STCB *callback, void *data)
int storePendingNClients(const StoreEntry *e)
static void storeClientCopy2(StoreEntry *e, store_client *sc)
store_client * storeClientListAdd(StoreEntry *e, void *data)
static bool CheckQuickAbortIsReasonable(StoreEntry *entry)
static StoreIOState::STRCB storeClientReadBody
static StoreIOState::STRCB storeClientReadHeader
void storeClose(StoreIOState::Pointer sio, int how)
void storeRead(StoreIOState::Pointer sio, char *buf, size_t size, off_t offset, StoreIOState::STRCB *callback, void *callback_data)
void storeSwapInStart(store_client *sc)
CodeContextPointer codeContext
Store client context.
CallbackData cbData
the first STCB callback parameter
STCB * callback_handler
where to deliver the answer
AsyncCall::Pointer notifier
a scheduled asynchronous finishCallback() call (or nil)