On Wed, Sep 28, 2022 at 5:17 PM Viresh Kumar <viresh.kumar@xxxxxxxxxx> wrote: > > On 28-09-22, 14:20, Bartosz Golaszewski wrote: > > Ok, so this is not correct. The doc for > > gpiod_edge_event_buffer_get_event() says: > > > > * @return Pointer to an event stored in the buffer. The lifetime of the > > * event is tied to the buffer object. Users must not free the event > > * returned by this function. > > > > We make no guarantees that the address returned by > > gpiod_edge_event_buffer_get_event() will still be valid after a call > > to gpiod_line_request_read_edge_event(). In fact the doc for the > > latter says: > > > > * @note Any exising events in the buffer are overwritten. This is not an > > * append operation. > > > > So we're being clear that after a call to > > gpiod_line_request_read_edge_event(), all previously returned edge > > event pointers are invalid unless the objects to which they point were > > explicitly copied. > > > > Current implementation does indeed work like what you describe but > > that behavior is not "contractually" guaranteed and can change even > > between minor releases. > > > > In C++ if you do: > > > > const edge_event& ev = buffer.get_event(0); > > request.read_edge_event(buffer); > > std::cout << ev << std::endl; > > > > You risk a segfault. > > > > My understanding is that Rust should not allow a crash in this > > situation by design. > > Hmm, so what exactly do we want to do here then ? > > - Don't allow events to be referenced ? i.e. make event_clone() the default > behavior ? > God no, that would be wasteful. > - Don't allow read_edge_event() to be called twice for a buffer ? that will be > inefficient though. > Not good either. > - Somehow guarantee that reference to all the events are dropped before issuing > read_edge_event() again, else make it fail ? I am not sure how straight > forward that can be though. In C++ the preferred way is to do buffer.get_event(0) which will return a constant reference. If you store that reference as const edge_event& ev = buffer.get_event(0) and reuse it after rereading into that buffer and the program crashes - that's on you. In most cases you should just do buffer.get_event(0).line_offset() etc. If you do: edge_event event = buffer.get_event(0); You'll copy the event and it will survive the overwriting of the buffer. I'm a Rust beginner but my understanding is that the whole idea of the language design is to *not* allow a situation where the program can crash. It should be detected at build-time. We must not rely on "contracts" defined by documentation. Is there a way to invalidate a reference in Rust? Have a small (cheap) object in the buffer which the event references and which would get dropped when reading into the buffer? Bart