Serenity Operating System
at master 82 lines 2.7 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * Copyright (c) 2021, sin-ack <sin-ack@protonmail.com> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#pragma once 9 10#include <AK/Badge.h> 11#include <AK/Checked.h> 12#include <AK/CircularQueue.h> 13#include <AK/HashMap.h> 14#include <AK/NonnullOwnPtr.h> 15#include <Kernel/API/InodeWatcherEvent.h> 16#include <Kernel/FileSystem/File.h> 17#include <Kernel/Forward.h> 18 19namespace Kernel { 20 21// A specific description of a watch. 22struct WatchDescription { 23 int wd; 24 Inode& inode; 25 unsigned event_mask; 26 27 static ErrorOr<NonnullOwnPtr<WatchDescription>> create(int wd, Inode& inode, unsigned event_mask) 28 { 29 return adopt_nonnull_own_or_enomem(new (nothrow) WatchDescription(wd, inode, event_mask)); 30 } 31 32private: 33 WatchDescription(int wd, Inode& inode, unsigned event_mask) 34 : wd(wd) 35 , inode(inode) 36 , event_mask(event_mask) 37 { 38 } 39}; 40 41class InodeWatcher final : public File { 42public: 43 static ErrorOr<NonnullRefPtr<InodeWatcher>> try_create(); 44 virtual ~InodeWatcher() override; 45 46 virtual bool can_read(OpenFileDescription const&, u64) const override; 47 virtual ErrorOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override; 48 // Can't write to an inode watcher. 49 virtual bool can_write(OpenFileDescription const&, u64) const override { return true; } 50 virtual ErrorOr<size_t> write(OpenFileDescription&, u64, UserOrKernelBuffer const&, size_t) override { return EIO; } 51 virtual ErrorOr<void> close() override; 52 53 virtual ErrorOr<NonnullOwnPtr<KString>> pseudo_path(OpenFileDescription const&) const override; 54 virtual StringView class_name() const override { return "InodeWatcher"sv; }; 55 virtual bool is_inode_watcher() const override { return true; } 56 57 void notify_inode_event(Badge<Inode>, InodeIdentifier, InodeWatcherEvent::Type, StringView name = {}); 58 59 ErrorOr<int> register_inode(Inode&, unsigned event_mask); 60 ErrorOr<void> unregister_by_wd(int); 61 void unregister_by_inode(Badge<Inode>, InodeIdentifier); 62 63private: 64 explicit InodeWatcher() { } 65 66 mutable Mutex m_lock; 67 68 struct Event { 69 int wd { 0 }; 70 InodeWatcherEvent::Type type { InodeWatcherEvent::Type::Invalid }; 71 OwnPtr<KString> path; 72 }; 73 CircularQueue<Event, 32> m_queue; 74 Checked<int> m_wd_counter { 1 }; 75 76 // NOTE: These two hashmaps provide two different ways of reaching the same 77 // watch description, so they will overlap. 78 HashMap<int, NonnullOwnPtr<WatchDescription>> m_wd_to_watches; 79 HashMap<InodeIdentifier, WatchDescription*> m_inode_to_watches; 80}; 81 82}