s.switchExclusiveToSharedLock();
}
+void
+Rock::DirMap::abortWriting(const sfileno fileno)
+{
+ debugs(79, 5, HERE << " abort writing slot at " << fileno <<
+ " in map [" << path << ']');
+ assert(valid(fileno));
+ Slot &s = shared->slots[fileno];
+ assert(s.state == Slot::Writeable);
+ freeLocked(s);
+}
+
bool
Rock::DirMap::putAt(const StoreEntry &e, const sfileno fileno)
{
return shared->slots[slotIdx(key)];
}
+/// frees the slot if (b) it is waiting to be freed and (a) we can lock it
void
Rock::DirMap::freeIfNeeded(Slot &s)
{
- const int idx = &s - shared->slots;
if (s.exclusiveLock()) {
- if (s.waitingToBeFreed.swap_if(true, false)) {
- memset(s.key_, 0, sizeof(s.key_));
- memset(&s.seBasics, 0, sizeof(s.seBasics));
- s.state = Slot::Empty;
+ if (s.waitingToBeFreed == true)
+ freeLocked(s);
+ else
s.releaseExclusiveLock();
- --shared->count;
- debugs(79, 5, HERE << " freed slot at " << idx << " in map [" <<
- path << ']');
- } else {
- s.releaseExclusiveLock();
- }
}
}
+/// unconditionally frees the already exclusively locked slot and releases lock
+void
+Rock::DirMap::freeLocked(Slot &s)
+{
+ memset(s.key_, 0, sizeof(s.key_));
+ memset(&s.seBasics, 0, sizeof(s.seBasics));
+ s.waitingToBeFreed = false;
+ s.state = Slot::Empty;
+ s.releaseExclusiveLock();
+ --shared->count;
+ debugs(79, 5, HERE << " freed slot at " << (&s - shared->slots) <<
+ " in map [" << path << ']');
+}
+
String
Rock::DirMap::sharedMemoryName()
{
}
void
-Rock::Slot::switchExclusiveToSharedLock() const
+Rock::Slot::switchExclusiveToSharedLock()
{
++readers; // must be done before we release exclusive control
releaseExclusiveLock();
DirMap(const char *const aPath, const int limit); ///< create a new shared DirMap
DirMap(const char *const aPath); ///< open an existing shared DirMap
- /// finds space for writing a new entry or returns nil
+ /// finds/reservers space for writing a new entry or returns nil
StoreEntryBasics *openForWriting(const cache_key *const key, sfileno &fileno);
- /// finish writing a new entry, leaves the entry opened for reading
+ /// successfully finish writing the entry, leaving it opened for reading
void closeForWriting(const sfileno fileno);
+ /// terminate writing the entry, freeing its slot for others to use
+ void abortWriting(const sfileno fileno);
/// stores entry info at the requested slot or returns false
bool putAt(const StoreEntry &e, const sfileno fileno);
Slot &slot(const cache_key *const key);
const StoreEntryBasics *openForReading(Slot &s);
void freeIfNeeded(Slot &s);
+ void freeLocked(Slot &s);
String sharedMemoryName();
static int SharedSize(const int limit);