diff options
author | Roman Smrž <roman.smrz@seznam.cz> | 2023-01-09 22:10:08 +0100 |
---|---|---|
committer | Roman Smrž <roman.smrz@seznam.cz> | 2023-01-14 23:08:37 +0100 |
commit | 10cb2e8956b47343666550dda55996cd7cfa6fbd (patch) | |
tree | a1e62884951329aad5fc76a7ae4f1a1953378102 | |
parent | 9ac0b00342c559cc4ad50061176ce2fd10482caa (diff) |
Storage: call watcher callbacks without holding lock
-rw-r--r-- | src/storage.cpp | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/src/storage.cpp b/src/storage.cpp index 9b49e96..2e948b0 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -367,15 +367,27 @@ void FilesystemStorage::inotifyWatch() event = (const struct inotify_event *) ptr; if (event->mask & IN_MOVED_TO) { - scoped_lock lock(watcherLock); - UUID type = watchMap[event->wd]; - if (auto mbid = UUID::fromString(event->name)) { - if (auto mbref = headRef(type, *mbid)) { - auto range = watchers.equal_range(type); - for (auto it = range.first; it != range.second; it++) - std::get<1>(it->second)(*mbid, *mbref); + vector<function<void(UUID id, const Digest &)>> callbacks; + optional<UUID> mbid; + optional<Digest> mbref; + + { + // Copy relevant callbacks to temporary array, so they + // can be called without holding the watcherLock. + + scoped_lock lock(watcherLock); + UUID type = watchMap[event->wd]; + if ((mbid = UUID::fromString(event->name))) { + if ((mbref = headRef(type, *mbid))) { + auto range = watchers.equal_range(type); + for (auto it = range.first; it != range.second; it++) + callbacks.push_back(std::get<1>(it->second)); + } } } + + for (const auto & cb : callbacks) + cb(*mbid, *mbref); } } } |