-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixed #100 (some pesky FS drivers can send paths with and without tra…
…iling slashes, now the code accounts for that). Improved the datastructures in FSEventsDirUpdateImpl - less mallocs, less caches trashing. Added logging as well. (#108)
- Loading branch information
1 parent
31ce792
commit bbe0d31
Showing
6 changed files
with
385 additions
and
299 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright (C) 2013-2024 Michael Kazakov. Subject to GNU General Public License version 3. | ||
#pragma once | ||
#include "FSEventsDirUpdate.h" | ||
#include <DiskArbitration/DiskArbitration.h> | ||
#include <CoreServices/CoreServices.h> | ||
#include <Base/spinlock.h> | ||
#include <filesystem> | ||
#include <Base/RobinHoodUtil.h> | ||
|
||
namespace nc::utility { | ||
|
||
class FSEventsDirUpdateImpl : public FSEventsDirUpdate | ||
{ | ||
public: | ||
uint64_t AddWatchPath(const char *_path, std::function<void()> _handler) override; | ||
|
||
void RemoveWatchPathWithTicket(uint64_t _ticket) override; | ||
|
||
// Implementation detail exposed for testability | ||
static bool ShouldFire(std::string_view _watched_path, | ||
size_t _num_events, | ||
const char *_event_paths[], | ||
const FSEventStreamEventFlags _event_flags[]) noexcept; | ||
|
||
private: | ||
struct WatchData { | ||
std::string_view path; // canonical fs representation, should include a trailing slash. points into hashmap | ||
FSEventStreamRef stream = nullptr; | ||
std::vector<std::pair<uint64_t, std::function<void()>>> handlers; | ||
}; | ||
|
||
using WatchesT = robin_hood:: | ||
unordered_node_map<std::string, WatchData, RHTransparentStringHashEqual, RHTransparentStringHashEqual>; | ||
|
||
void OnVolumeDidUnmount(const std::string &_on_path) override; | ||
|
||
static void DiskDisappeared(DADiskRef disk, void *context); | ||
static void FSEventsDirUpdateCallback(ConstFSEventStreamRef streamRef, | ||
void *userData, | ||
size_t numEvents, | ||
void *eventPaths, | ||
const FSEventStreamEventFlags eventFlags[], | ||
const FSEventStreamEventId eventIds[]); | ||
static FSEventStreamRef CreateEventStream(const std::string &path, void *context); | ||
|
||
spinlock m_Lock; | ||
WatchesT m_Watches; // path -> watch data; | ||
std::atomic_ulong m_LastTicket{1}; // no #0 ticket, it's an error code | ||
}; | ||
|
||
} // namespace nc::utility |
Oops, something went wrong.