CBDATA_CLASS(store_client);
public:
- store_client(StoreEntry *);
+ explicit store_client(StoreEntry *);
~store_client();
/// An offset into the stored response bytes, including the HTTP response
object_ok(true),
copiedSize(0)
{
+ Assure(entry);
+ entry->lock("store_client");
+
flags.disk_io_pending = false;
flags.store_copying = false;
++ entry->refcount;
}
store_client::~store_client()
-{}
+{
+ assert(entry);
+ entry->unlock("store_client");
+}
/* copy bytes requested by the client */
void
if (len > 0 && rep && entry->mem_obj->inmem_lo == 0 && entry->objectLen() <= (int64_t)Config.Store.maxInMemObjSize && Config.onoff.memory_cache_disk) {
storeGetMemSpace(len);
- // The above may start to free our object so we need to check again
+ // recheck for the above call may purge entry's data from the memory cache
if (entry->mem_obj->inmem_lo == 0) {
/* Copy read data back into memory.
* copyInto.offset includes headers, which is what mem cache needs
#endif
+ // We must lock to safely dereference e below, after deleting sc and after
+ // calling CheckQuickAbortIsReasonable().
+ e->lock("storeUnregister");
+
// XXX: We might be inside sc store_client method somewhere up the call
// stack. TODO: Convert store_client to AsyncJob to make destruction async.
delete sc;
- assert(e->locked());
- // An entry locked by others may be unlocked (and destructed) by others, so
- // we must lock again to safely dereference e after CheckQuickAbortIsReasonable().
- e->lock("storeUnregister");
-
if (CheckQuickAbortIsReasonable(e))
e->abort();
else