~aleteoryx/muditaos

ref: 1f50621c2fdb5da142cbfd388d091200594dedd1 muditaos/module-vfs/include/internal/purefs/fs/notifier.hpp -rw-r--r-- 4.5 KiB
1f50621c — Lefucjusz [MOS-184] Fix unit tests not failing on duplicate test case 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once

#include <map>
#include <string>
#include <memory>
#include <optional>
#include <purefs/fs/fsnotify.hpp>
#include <purefs/fs/inotify_flags.hpp>

namespace sys
{
    class Service;
}
namespace cpp_freertos
{
    class MutexRecursive;
}
namespace purefs::fs::internal
{
    //! Internal class related to the notify VFS events
    class notifier
    {
        //! Container for path item
        struct path_item
        {
            path_item(std::string_view _path, bool _read_only) : path(_path), read_only(_read_only)
            {}
            const std::string path;
            const bool read_only;
        };
        //! Container for service and subscribed events
        struct service_item
        {
            service_item(std::weak_ptr<sys::Service> _service, inotify_flags _subscribed_events)
                : service(_service), subscribed_events(_subscribed_events)
            {}
            const std::weak_ptr<sys::Service> service;
            const inotify_flags subscribed_events;
        };
        //! Container for the the event
        using container_t = std::multimap<std::string, service_item>;

      public:
        notifier();
        notifier(notifier &) = delete;
        notifier &operator=(notifier &) = delete;
        virtual ~notifier();
        //! Iterator for the registered event
        using item_it = container_t::iterator;
        /**
         * @brief Register selected path for the monitoring
         *
         * @param path Path for monitor
         * @param owner Service which should be notified
         * @param flags Event mask which should be monitored
         * @return std::optional<item_it>  Registered event iterator or nothing if failed
         */
        auto register_path(std::string_view path, std::shared_ptr<sys::Service> owner, inotify_flags flags)
            -> std::optional<item_it>;
        /**
         * @brief Unregister selected path from monitoring
         *
         * @param item Iterator returned by the @see register_path method
         */
        auto unregister_path(item_it item) -> void;
        /**
         * @brief Internal method called on file open
         *
         * @param path Open file path
         * @param fd File descriptor assigned by open method
         * @param ro File is opened in read only mode
         */
        auto notify_open(std::string_view path, int fd, bool ro) const -> void;
        /**
         * @brief Internal method called on closing gile
         *
         * @param fd File descriptor
         */
        auto notify_close(int fd) const -> void;
        /**
         * @brief Notify for event on the file system
         *
         * @param fd File descriptor for file
         * @param mask Filesystem event type
         */
        auto notify(int fd, inotify_flags mask) const -> void;
        /**
         * @brief Notify for event on filesystem on path change
         *
         * @param path Path before event occured
         * @param path_prv Path after event occured
         * @param mask Filesystem event type
         */
        auto notify(std::string_view path, std::string_view path_prv, inotify_flags mask) const -> void;
        /**
         * @brief Notify for event on the filesystem
         *
         * @param path Path related to th event
         * @param mask Filesystem event type
         */
        auto notify(std::string_view path, inotify_flags mask) const -> void
        {
            notify(path, "", mask);
        }

      private:
        /**
         * @brief Private method called for send file monitor event
         *
         * @param svc Target service
         * @param flags Filesystem event type
         * @param name Path related to the event before change
         * @param name_dst Path realated to the event after change
         */
        virtual auto send_notification(std::shared_ptr<sys::Service> svc,
                                       inotify_flags flags,
                                       std::string_view name,
                                       std::string_view name_dst) const -> void;

      private:
        //! Events container
        container_t m_events;
        //! Map file descriptors with path assiociated with it
        mutable std::map<int, path_item> m_fd_map;
        //! Internal mutex for lock the object
        std::unique_ptr<cpp_freertos::MutexRecursive> m_lock;
    };
} // namespace purefs::fs::internal