]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Do not broadcast changes if there are no remote readers.
authorAlex Rousskov <rousskov@measurement-factory.com>
Tue, 25 Jun 2013 19:19:28 +0000 (13:19 -0600)
committerAlex Rousskov <rousskov@measurement-factory.com>
Tue, 25 Jun 2013 19:19:28 +0000 (13:19 -0600)
New/future readers should anchor themselves to the cache in order to get the
earlier updates they missed.

src/CollapsedForwarding.cc
src/Store.h
src/SwapDir.h
src/Transients.cc
src/Transients.h
src/ipc/StoreMap.cc
src/ipc/StoreMap.h
src/store_dir.cc

index 629327d5465024493ea8b704383ec6c80bb63654..345f1b340f7021445043b0cf3b7ff8e3cdf267d1 100644 (file)
@@ -8,6 +8,7 @@
 #include "ipc/Messages.h"
 #include "ipc/Port.h"
 #include "ipc/TypedMsgHdr.h"
+#include "MemObject.h"
 #include "CollapsedForwarding.h"
 #include "globals.h"
 #include "SquidConfig.h"
@@ -50,6 +51,12 @@ CollapsedForwarding::Broadcast(const StoreEntry &e)
     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));
index d2131fe38805ac75ef83299172b3c8a2680d9b4f..e689680f3dd0c728ff67bd5b9cf4f2ffa87f188d 100644 (file)
@@ -392,6 +392,11 @@ public:
     /// 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
index fc2ed8f74936019771ea6ad288a5ea58f1fffbe8..68fe0beeb29d8152a7d7f26c2037c13b352f1a3e 100644 (file)
@@ -64,6 +64,7 @@ public:
     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);
index 340f2ee599f2e40a3ac9ca75b3f7f559a6423dcf..c6967b84092bd2d4a353228b70fde5c089158a82 100644 (file)
@@ -306,6 +306,16 @@ Transients::completeWriting(const 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)
 {
index 12d784d2b5d2e0b5781eb456f382af1c3f6aeb28..cbe2138f6ce205937934b78bb9b158fb6f24d2e2 100644 (file)
@@ -36,6 +36,9 @@ public:
     /// 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);
 
index 7c602fb1c77d9d49685e3d66fa144bb0898300f6..db26250d0f75df3729f95cb39e3102dfc9f78703 100644 (file)
@@ -212,6 +212,13 @@ Ipc::StoreMap::peekAtReader(const sfileno fileno) const
     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)
 {
index ddcf88afb9bb6b98e461288f2e7dd28d474dbd5f..c1edb2378b1598eab4f26255a7c60024778b3116 100644 (file)
@@ -152,6 +152,9 @@ public:
     /// 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
index f1197c2ca30fd0aac91696cadd9f9592d2910ecd..6584f360dcc315f350428f9a838e7bd73129534e 100644 (file)
@@ -918,6 +918,13 @@ StoreController::transientsCompleteWriting(StoreEntry &e)
     }
 }
 
+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)
 {