]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/ipc/ReadWriteLock.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / ipc / ReadWriteLock.cc
index bca150133aee20d65bcdd4443f271df3f7012492..de6894a7c5a1f6346529ed8d38a2be15b91e55ee 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
 #include "ipc/ReadWriteLock.h"
 #include "Store.h"
 
+void Ipc::AssertFlagIsSet(std::atomic_flag &flag)
+{
+    // If the flag was false, then we set it to true and assert. A true flag
+    // may help keep other processes away from this broken entry.
+    // Otherwise, we just set an already set flag, which is probably a no-op.
+    assert(flag.test_and_set(std::memory_order_relaxed));
+}
+
 bool
 Ipc::ReadWriteLock::lockShared()
 {
@@ -37,6 +45,18 @@ Ipc::ReadWriteLock::lockExclusive()
     return false;
 }
 
+bool
+Ipc::ReadWriteLock::lockHeaders()
+{
+    if (lockShared()) {
+        if (!updating.test_and_set(std::memory_order_acquire))
+            return true; // we got here first
+        // the updating lock was already set by somebody else
+        unlockShared();
+    }
+    return false;
+}
+
 void
 Ipc::ReadWriteLock::unlockShared()
 {
@@ -54,6 +74,14 @@ Ipc::ReadWriteLock::unlockExclusive()
     --writeLevel;
 }
 
+void
+Ipc::ReadWriteLock::unlockHeaders()
+{
+    AssertFlagIsSet(updating);
+    updating.clear(std::memory_order_release);
+    unlockShared();
+}
+
 void
 Ipc::ReadWriteLock::switchExclusiveToShared()
 {