Re: [PATCH V6 3/8] libgpiod: Add rust wrapper crate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux