On Tue, Sep 27, 2022 at 3:57 PM Viresh Kumar <viresh.kumar@xxxxxxxxxx> wrote: > > 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(). > So what happens if I do this: let buf = edge::event::Buffer::new(10)?; let request = chip.request_lines(&rconfig, &lconfig)?; let count = request.read_edge_events(&buffer)?; let event = buffer.event(0); let count = request.read_edge_events(&buffer)?; println!("line: {}", event.line_offset()); ? > > 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.