#include "ipc/Messages.h"
#include "ipc/Port.h"
#include "ipc/TypedMsgHdr.h"
+#include "MemObject.h"
#include "CollapsedForwarding.h"
#include "globals.h"
#include "SquidConfig.h"
if (!queue.get())
return;
+ if (!e.mem_obj || e.mem_obj->xitTable.index < 0 ||
+ !Store::Root().transientReaders(e)) {
+ debugs(17, 7, "not broadcasting " << e << " changes to nobody");
+ return;
+ }
+
CollapsedForwardingMsg msg;
msg.sender = KidIdentifier;
memcpy(msg.key, e.key, sizeof(msg.key));
/// calls Root().transients->abandon() if transients are tracked
virtual void transientsAbandon(StoreEntry &e) {}
+ // XXX: This method belongs to Store::Root/StoreController, but it is here
+ // to avoid casting Root() to StoreController until Root() API is fixed.
+ /// number of the transient entry readers some time ago
+ virtual int transientReaders(const StoreEntry &e) const { return 0; }
+
// XXX: This method belongs to Store::Root/StoreController, but it is here
// to avoid casting Root() to StoreController until Root() API is fixed.
/// disassociates the entry from the intransit table
virtual void handleIdleEntry(StoreEntry &e);
virtual void transientsCompleteWriting(StoreEntry &e);
virtual void transientsAbandon(StoreEntry &e);
+ virtual int transientReaders(const StoreEntry &e) const;
virtual void transientsDisconnect(MemObject &mem_obj);
virtual void memoryOut(StoreEntry &e, const bool preserveSwappable);
virtual void memoryUnlink(StoreEntry &e);
}
}
+int
+Transients::readers(const StoreEntry &e) const
+{
+ if (e.mem_obj && e.mem_obj->xitTable.index >= 0) {
+ assert(map);
+ return map->peekAtEntry(e.mem_obj->xitTable.index).lock.readers;
+ }
+ return 0;
+}
+
void
Transients::disconnect(MemObject &mem_obj)
{
/// whether an in-transit entry is now abandoned by its writer
bool abandoned(const StoreEntry &e) const;
+ /// number of entry readers some time ago
+ int readers(const StoreEntry &e) const;
+
/// the caller is done writing or reading this entry
void disconnect(MemObject &mem_obj);
return NULL;
}
+const Ipc::StoreMap::Anchor &
+Ipc::StoreMap::peekAtEntry(const sfileno fileno) const
+{
+ assert(valid(fileno));
+ return shared->slots[fileno].anchor;
+}
+
void
Ipc::StoreMap::freeEntry(const sfileno fileno)
{
/// only works on locked entries; returns nil unless the slice is readable
const Anchor *peekAtReader(const sfileno fileno) const;
+ /// only works on locked entries; returns the corresponding Anchor
+ const Anchor &peekAtEntry(const sfileno fileno) const;
+
/// free the entry if possible or mark it as waiting to be freed if not
void freeEntry(const sfileno fileno);
/// free the entry if possible or mark it as waiting to be freed if not
}
}
+int
+StoreController::transientReaders(const StoreEntry &e) const
+{
+ return (transients && e.mem_obj && e.mem_obj->xitTable.index >= 0) ?
+ transients->readers(e) : 0;
+}
+
void
StoreController::transientsDisconnect(MemObject &mem_obj)
{