On Tue, 27 Sept 2022 at 18:48, Bartosz Golaszewski <brgl@xxxxxxxx> wrote: > On Mon, Sep 26, 2022 at 5:27 PM Viresh Kumar <viresh.kumar@xxxxxxxxxx> wrote: > > This is where Rust's memory safety comes in. If you see the design of > > the 'structure Event', it saves a reference to the 'struct BufferInternal'. > > The drop() implementation of BufferInternal calls: > > gpiod_edge_event_buffer_free(), but it won't get called unless all the > > references to it have gone out of scope. So untill the time user is still > > using any of the events, the buffer won't get freed. So we will never > > have invalid reference issue here. > > You've got to help me out here, just looking at the code doesn't make > things clear for me. Just to clarify, Buffer is just a wrapper over BufferInternal, you can think of them as the same entity for simplicity. > Am I right to understand that each Event holds a reference to the > BufferInternal object and it will only be destroyed when the last > event is dropped? Yes. But the buffer variable itself too holds a reference to the Buffer. Even if all the events are dropped, the buffer won't get free unless the buffer variable gets dropped too. > If we read new events into the buffer, does that > create a new BufferInternal? No. It uses the existing buffer only, that we created using Buffer::new(). > Is that efficient? Aren't we allocating > memory for each new BufferInternal at every read? No, we reuse the same buffer for all the reads. If you see the gpiomon.rs example, it shows how this is being done. The buffer (and internal buffer too) is created only once in line 42: let buffer = edge::event::Buffer::new(1)?; This allocates the memory for buffer only once, after that we continue reading from the same buffer. The BufferInternal structure is enclosed within an Arc<> instance, which is "Atomically Reference Counted", very much like kref_get/put in kernel. Unless the last reference is dropped, it stays. Hope I was able to clarify this here.