vfs/directory/watchers/
event_producers.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! When generating a watcher event, one needs "a list of names" that are then converted into
6//! buffers sent to the watchers.  In a sense, an iterator over a list of strings would work, but
7//! in order to avoid copying the data around, this namespace provides a more specialized version
8//! of this abstraction.
9
10use fidl_fuchsia_io as fio;
11use static_assertions::assert_eq_size;
12
13/// Watcher event producer, that generates buffers filled with watcher events.  Watchers use this
14/// API to obtain buffers that are then sent to the actual watchers.  Every producer may generate
15/// multiple events, but they all need to be of the same type, as returned by [`Self::event()`] and
16/// [`Self::mask()`] methods.
17pub trait EventProducer {
18    /// Returns a mask that represents the type of events this producer can generate, as one of the
19    /// `fidl_fuchsia_io::WatchMask::*` constants.  There might be only one bit set and it should
20    /// correspond to the event returned by the [`Self::event()`] method.  It is a duplication, but it
21    /// helps the callers that need both masks and event IDs.
22    fn mask(&self) -> fio::WatchMask;
23
24    /// Returns an event ID this event producer will use to populate the buffers, as one of the
25    /// `fidl_fuchsia_io::WatchEvent::*` constants.  Must match what [`Self::mask()`], returns, see
26    /// there for details.
27    fn event(&self) -> fio::WatchEvent;
28
29    /// Checks if this producer can create another buffer, returning `true` if it can.  This method
30    /// does not actually need to construct the buffer just yet, as an optimization if it will not
31    /// be needed.
32    fn prepare_for_next_buffer(&mut self) -> bool;
33
34    /// Returns a copy of the current buffer prepared by this producer.  This method will be the
35    /// one constructing a buffer, if necessary, after a preceding call to
36    /// [`Self::prepare_for_next_buffer()`].
37    ///
38    /// Note that this method will keep returning copies of the same buffer, until
39    /// [`Self::prepare_for_next_buffer()`] is not called explicitly.
40    fn buffer(&mut self) -> Vec<u8>;
41}
42
43/// Common mechanism used by both [`StaticVecEventProducer`] and, later, [`SinkEventProducer`].
44struct CachingEventProducer {
45    mask: fio::WatchMask,
46    event: fio::WatchEvent,
47    current_buffer: Option<Vec<u8>>,
48}
49
50impl CachingEventProducer {
51    fn new(mask: fio::WatchMask, event: fio::WatchEvent) -> Self {
52        CachingEventProducer { mask, event, current_buffer: None }
53    }
54
55    fn mask(&self) -> fio::WatchMask {
56        self.mask
57    }
58
59    fn event(&self) -> fio::WatchEvent {
60        self.event
61    }
62
63    fn prepare_for_next_buffer(&mut self) {
64        self.current_buffer = None;
65    }
66
67    /// Users of [`CachingEventProducer`] should use this method to implement
68    /// [`EventProducer::buffer`].  `fill_buffer` is a callback used to populate the buffer when
69    /// necessary.  It's 'u8' argument is the event ID used by this producer.
70    fn buffer<FillBuffer>(&mut self, fill_buffer: FillBuffer) -> Vec<u8>
71    where
72        FillBuffer: FnOnce(fio::WatchEvent) -> Vec<u8>,
73    {
74        match &self.current_buffer {
75            Some(buf) => buf.clone(),
76            None => {
77                let buf = fill_buffer(self.event);
78                self.current_buffer = Some(buf.clone());
79                buf
80            }
81        }
82    }
83}
84
85/// An [`EventProducer`] that uses a `Vec<String>` with names of the entires to be put into the
86/// watcher event.
87pub struct StaticVecEventProducer {
88    cache: CachingEventProducer,
89    names: Vec<String>,
90    next: usize,
91}
92
93impl StaticVecEventProducer {
94    /// Constructs a new [`EventProducer`] that is producing names form the specified list,
95    /// building events of type `WatchEvent::Added`.  `names` is not allowed to be empty.
96    pub fn added(names: Vec<String>) -> Self {
97        Self::new(fio::WatchMask::ADDED, fio::WatchEvent::Added, names)
98    }
99
100    /// Constructs a new [`EventProducer`] that is producing names form the specified list,
101    /// building events of type `WatchEvent::Removed`.  `names` is not allowed to be empty.
102    pub fn removed(names: Vec<String>) -> Self {
103        Self::new(fio::WatchMask::REMOVED, fio::WatchEvent::Removed, names)
104    }
105
106    /// Constructs a new [`EventProducer`] that is producing names form the specified list,
107    /// building events of type `WatchEvent::Existing`.  `names` is not allowed to be empty.
108    pub fn existing(names: Vec<String>) -> Self {
109        Self::new(fio::WatchMask::EXISTING, fio::WatchEvent::Existing, names)
110    }
111
112    fn new(mask: fio::WatchMask, event: fio::WatchEvent, names: Vec<String>) -> Self {
113        debug_assert!(!names.is_empty());
114        Self { cache: CachingEventProducer::new(mask, event), names, next: 0 }
115    }
116
117    // Can not use `&mut self` here as it would "lock" the whole object disallowing the
118    // `self.cache.buffer()` call where we want to pass this method in a closure.
119    fn fill_buffer(event: fio::WatchEvent, next: &mut usize, names: &mut Vec<String>) -> Vec<u8> {
120        let mut buffer = vec![];
121
122        while *next < names.len() {
123            if !encode_name(&mut buffer, event, &names[*next]) {
124                break;
125            }
126            *next += 1;
127        }
128
129        buffer
130    }
131}
132
133impl EventProducer for StaticVecEventProducer {
134    fn mask(&self) -> fio::WatchMask {
135        self.cache.mask()
136    }
137
138    fn event(&self) -> fio::WatchEvent {
139        self.cache.event()
140    }
141
142    fn prepare_for_next_buffer(&mut self) -> bool {
143        self.cache.prepare_for_next_buffer();
144        self.next < self.names.len()
145    }
146
147    fn buffer(&mut self) -> Vec<u8> {
148        let cache = &mut self.cache;
149        let next = &mut self.next;
150        let names = &mut self.names;
151        cache.buffer(|event| Self::fill_buffer(event, next, names))
152    }
153}
154
155/// An event producer for an event containing only one name.  It is slightly optimized, but
156/// otherwise functionally equivalent to the [`StaticVecEventProducer`] with an array of one
157/// element.
158pub struct SingleNameEventProducer {
159    producer: SingleBufferEventProducer,
160}
161
162impl SingleNameEventProducer {
163    /// Constructs a new [`SingleNameEventProducer`] that will produce an event for one name of
164    /// type `WatchEvent::Deleted`. Deleted refers to the directory the watcher itself is on, and
165    /// therefore statically refers to itself as ".".
166    pub fn deleted() -> Self {
167        Self::new(fio::WatchMask::DELETED, fio::WatchEvent::Deleted, ".")
168    }
169
170    /// Constructs a new [`SingleNameEventProducer`] that will produce an event for one name of
171    /// type `WatchEvent::Added`.
172    pub fn added(name: &str) -> Self {
173        Self::new(fio::WatchMask::ADDED, fio::WatchEvent::Added, name)
174    }
175
176    /// Constructs a new [`SingleNameEventProducer`] that will produce an event for one name of
177    /// type `WatchEvent::Removed`.
178    pub fn removed(name: &str) -> Self {
179        Self::new(fio::WatchMask::REMOVED, fio::WatchEvent::Removed, name)
180    }
181
182    /// Constructs a new [`SingleNameEventProducer`] that will produce an event for one name of
183    /// type `WatchEvent::Existing`.
184    pub fn existing(name: &str) -> Self {
185        Self::new(fio::WatchMask::EXISTING, fio::WatchEvent::Existing, name)
186    }
187
188    /// Constructs a new [`SingleNameEventProducer`] that will produce an `WatchEvent::Idle` event.
189    pub fn idle() -> Self {
190        Self::new(fio::WatchMask::IDLE, fio::WatchEvent::Idle, "")
191    }
192
193    fn new(mask: fio::WatchMask, event: fio::WatchEvent, name: &str) -> Self {
194        let mut buffer = vec![];
195        encode_name(&mut buffer, event, name);
196
197        Self { producer: SingleBufferEventProducer::new(mask, event, buffer) }
198    }
199}
200
201impl EventProducer for SingleNameEventProducer {
202    fn mask(&self) -> fio::WatchMask {
203        self.producer.mask()
204    }
205
206    fn event(&self) -> fio::WatchEvent {
207        self.producer.event()
208    }
209
210    fn prepare_for_next_buffer(&mut self) -> bool {
211        self.producer.prepare_for_next_buffer()
212    }
213
214    fn buffer(&mut self) -> Vec<u8> {
215        self.producer.buffer()
216    }
217}
218
219pub(crate) fn encode_name(buffer: &mut Vec<u8>, event: fio::WatchEvent, name: &str) -> bool {
220    if buffer.len() + (2 + name.len()) > fio::MAX_BUF as usize {
221        return false;
222    }
223
224    // We are going to encode the file name length as u8.
225    debug_assert!(u8::max_value() as u64 >= fio::MAX_NAME_LENGTH);
226
227    buffer.push(event.into_primitive());
228    buffer.push(name.len() as u8);
229    buffer.extend_from_slice(name.as_bytes());
230    true
231}
232
233enum SingleBufferEventProducerState {
234    Start,
235    FirstEvent,
236    Done,
237}
238
239/// An event producer for an event that has one buffer of data.
240pub struct SingleBufferEventProducer {
241    mask: fio::WatchMask,
242    event: fio::WatchEvent,
243    buffer: Vec<u8>,
244    state: SingleBufferEventProducerState,
245}
246
247impl SingleBufferEventProducer {
248    /// Constructs a new [`SingleBufferEventProducer`] that will produce an event for one name of
249    /// type `WatchEvent::Existing`.
250    pub fn existing(buffer: Vec<u8>) -> Self {
251        assert_eq_size!(usize, u64);
252        debug_assert!(buffer.len() as u64 <= fio::MAX_BUF);
253        Self::new(fio::WatchMask::EXISTING, fio::WatchEvent::Existing, buffer)
254    }
255
256    fn new(mask: fio::WatchMask, event: fio::WatchEvent, buffer: Vec<u8>) -> Self {
257        assert_eq_size!(usize, u64);
258        debug_assert!(buffer.len() as u64 <= fio::MAX_BUF);
259        Self { mask, event, buffer, state: SingleBufferEventProducerState::Start }
260    }
261}
262
263impl EventProducer for SingleBufferEventProducer {
264    fn mask(&self) -> fio::WatchMask {
265        self.mask
266    }
267
268    fn event(&self) -> fio::WatchEvent {
269        self.event
270    }
271
272    fn prepare_for_next_buffer(&mut self) -> bool {
273        match self.state {
274            SingleBufferEventProducerState::Start => {
275                self.state = SingleBufferEventProducerState::FirstEvent;
276                true
277            }
278            SingleBufferEventProducerState::FirstEvent => {
279                self.state = SingleBufferEventProducerState::Done;
280                false
281            }
282            SingleBufferEventProducerState::Done => false,
283        }
284    }
285
286    fn buffer(&mut self) -> Vec<u8> {
287        self.buffer.clone()
288    }
289}