On 17-12-21, 10:12, Bartosz Golaszewski wrote: > No, it's a different story altogether. In C the buffer allocates > memory for events and when you "get" an event, you only have a pointer > to the memory space in the buffer that you must not free. But you can > "copy" an event with gpiod_edge_event_copy() which returns you a deep > copy of the event that will survive the parent and that must be freed > with gpiod_edge_event_free(). This is done so that by default we try > to limit the number of allocations (as there can be a lot of events) > unless the user decides to manually copy the event. > > In C++ I used that mechanism together with the buffer's const > event_get() and event's copy assignment operator. "Getting" an event > returns a const reference to the event (still in buffer's memory) but > copying it triggers a deep copy. The memory management is of course > handled by the destructor. > > This is not used in Python as speed is no longer a concern and we'd be > creating new python objects anyway. But in Rust, I think it makes > sense to reuse this mechanism. Ahh, what about this then, it just caches all the values when the event is requested ? pub struct EdgeEvent { event_type: LineEdgeEvent, timestamp: Duration, line_offset: u32, global_seqno: u64, line_seqno: u64, } impl EdgeEvent { /// Get an event stored in the buffer. pub fn new(buffer: &EdgeEventBuffer, index: u64) -> Result<Self> { let event = unsafe { bindings::gpiod_edge_event_buffer_get_event(buffer.buffer(), index) }; if event.is_null() { return Err(Error::OperationFailed( "Gpio EdgeEvent buffer-get-event", IoError::last(), )); } Ok(Self { event_type: LineEdgeEvent::new(unsafe { bindings::gpiod_edge_event_get_event_type(event) } as u32)?, timestamp: Duration::from_nanos(unsafe { bindings::gpiod_edge_event_get_timestamp(event) }), line_offset: unsafe { bindings::gpiod_edge_event_get_line_offset(event) }, global_seqno: unsafe { bindings::gpiod_edge_event_get_global_seqno(event) }, line_seqno: unsafe { bindings::gpiod_edge_event_get_line_seqno(event) }, }) } /// Get the event type. pub fn get_event_type(&self) -> LineEdgeEvent { self.event_type } /// Get the timestamp of the event. pub fn get_timestamp(&self) -> Duration { self.timestamp } /// Get the offset of the line on which the event was triggered. pub fn get_line_offset(&self) -> u32 { self.line_offset } /// Get the global sequence number of this event. /// /// Returns sequence number of the event relative to all lines in the /// associated line request. pub fn get_global_seqno(&self) -> u64 { self.global_seqno } /// Get the event sequence number specific to concerned line. /// /// Returns sequence number of the event relative to this line within the /// lifetime of the associated line request. pub fn get_line_seqno(&self) -> u64 { self.line_seqno } } -- viresh