mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +00:00
Kernel: Protect Inode's list of watchers with spinlock instead of mutex
This commit is contained in:
parent
210689281f
commit
e0d9472ced
Notes:
sideshowbarker
2024-07-17 19:50:56 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/e0d9472ced9
2 changed files with 28 additions and 27 deletions
|
@ -93,9 +93,9 @@ Inode::Inode(FileSystem& fs, InodeIndex index)
|
|||
|
||||
Inode::~Inode()
|
||||
{
|
||||
for (auto& watcher : m_watchers) {
|
||||
m_watchers.for_each([&](auto& watcher) {
|
||||
watcher->unregister_by_inode({}, identifier());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Inode::will_be_destroyed()
|
||||
|
@ -156,17 +156,19 @@ bool Inode::unbind_socket()
|
|||
|
||||
ErrorOr<void> Inode::register_watcher(Badge<InodeWatcher>, InodeWatcher& watcher)
|
||||
{
|
||||
MutexLocker locker(m_inode_lock);
|
||||
VERIFY(!m_watchers.contains(&watcher));
|
||||
TRY(m_watchers.try_set(&watcher));
|
||||
return m_watchers.with([&](auto& watchers) -> ErrorOr<void> {
|
||||
VERIFY(!watchers.contains(&watcher));
|
||||
TRY(watchers.try_set(&watcher));
|
||||
return {};
|
||||
});
|
||||
}
|
||||
|
||||
void Inode::unregister_watcher(Badge<InodeWatcher>, InodeWatcher& watcher)
|
||||
{
|
||||
MutexLocker locker(m_inode_lock);
|
||||
VERIFY(m_watchers.contains(&watcher));
|
||||
m_watchers.remove(&watcher);
|
||||
m_watchers.with([&](auto& watchers) {
|
||||
VERIFY(watchers.contains(&watcher));
|
||||
watchers.remove(&watcher);
|
||||
});
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<FIFO>> Inode::fifo()
|
||||
|
@ -197,49 +199,43 @@ void Inode::set_metadata_dirty(bool metadata_dirty)
|
|||
if (m_metadata_dirty) {
|
||||
// FIXME: Maybe we should hook into modification events somewhere else, I'm not sure where.
|
||||
// We don't always end up on this particular code path, for instance when writing to an ext2fs file.
|
||||
for (auto& watcher : m_watchers) {
|
||||
m_watchers.for_each([&](auto& watcher) {
|
||||
watcher->notify_inode_event({}, identifier(), InodeWatcherEvent::Type::MetadataModified);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Inode::did_add_child(InodeIdentifier, StringView name)
|
||||
{
|
||||
MutexLocker locker(m_inode_lock);
|
||||
|
||||
for (auto& watcher : m_watchers) {
|
||||
m_watchers.for_each([&](auto& watcher) {
|
||||
watcher->notify_inode_event({}, identifier(), InodeWatcherEvent::Type::ChildCreated, name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Inode::did_remove_child(InodeIdentifier, StringView name)
|
||||
{
|
||||
MutexLocker locker(m_inode_lock);
|
||||
|
||||
if (name == "." || name == "..") {
|
||||
// These are just aliases and are not interesting to userspace.
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& watcher : m_watchers) {
|
||||
m_watchers.for_each([&](auto& watcher) {
|
||||
watcher->notify_inode_event({}, identifier(), InodeWatcherEvent::Type::ChildDeleted, name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Inode::did_modify_contents()
|
||||
{
|
||||
MutexLocker locker(m_inode_lock);
|
||||
for (auto& watcher : m_watchers) {
|
||||
m_watchers.for_each([&](auto& watcher) {
|
||||
watcher->notify_inode_event({}, identifier(), InodeWatcherEvent::Type::ContentModified);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Inode::did_delete_self()
|
||||
{
|
||||
MutexLocker locker(m_inode_lock);
|
||||
for (auto& watcher : m_watchers) {
|
||||
m_watchers.for_each([&](auto& watcher) {
|
||||
watcher->notify_inode_event({}, identifier(), InodeWatcherEvent::Type::Deleted);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ErrorOr<void> Inode::prepare_to_write_data()
|
||||
|
@ -370,4 +366,9 @@ void Inode::remove_flocks_for_description(OpenFileDescription const& description
|
|||
m_flocks.remove(i--);
|
||||
}
|
||||
}
|
||||
bool Inode::has_watchers() const
|
||||
{
|
||||
return !m_watchers.with([&](auto& watchers) { return watchers.is_empty(); });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ public:
|
|||
static void sync_all();
|
||||
void sync();
|
||||
|
||||
bool has_watchers() const { return !m_watchers.is_empty(); }
|
||||
bool has_watchers() const;
|
||||
|
||||
ErrorOr<void> register_watcher(Badge<InodeWatcher>, InodeWatcher&);
|
||||
void unregister_watcher(Badge<InodeWatcher>, InodeWatcher&);
|
||||
|
@ -118,7 +118,7 @@ private:
|
|||
InodeIndex m_index { 0 };
|
||||
WeakPtr<Memory::SharedInodeVMObject> m_shared_vmobject;
|
||||
RefPtr<LocalSocket> m_socket;
|
||||
HashTable<InodeWatcher*> m_watchers;
|
||||
SpinlockProtected<HashTable<InodeWatcher*>> m_watchers;
|
||||
bool m_metadata_dirty { false };
|
||||
RefPtr<FIFO> m_fifo;
|
||||
IntrusiveListNode<Inode> m_inode_list_node;
|
||||
|
|
Loading…
Reference in a new issue