[Spice-devel] [PATCH 08/14] Use RAII to cleanup stream in case of exception or return

Christophe de Dinechin christophe.de.dinechin at gmail.com
Sat Feb 17 12:44:00 UTC 2018



> On 15 Feb 2018, at 15:35, Frediano Ziglio <fziglio at redhat.com> wrote:
> 
>>> 
>>> On 15 Feb 2018, at 11:04, Frediano Ziglio <fziglio at redhat.com> wrote:
>>> 
>>>> 
>>>> From: Christophe de Dinechin <dinechin at redhat.com>
>>>> 
>>>> This lets us get rid of C-style 'goto done' in do_capture.
>>>> 
>>>> Signed-off-by: Christophe de Dinechin <dinechin at redhat.com>
>>> 
>>> I honestly prefer the "defer" style way.
>> 
>> The standard C++ practice for resource management is RAII, not defer. RAII is
>> a composable abstraction, i.e. I can pile structs in structs and it still
>> works.
>> 
> 
> RAII is supposed to encapsulate a resource, your patch is encapsulating
> the allocation and disposal of an external resource, exactly as the defer
> generated code/data are doing.
> The difference is that your code handle only FILE* while defer supports
> different cases.
> In a perfect world everything would be already encapsulated in RAII
> objects but dealing with C objects the defer style provides much more
> reuse.
> 
>> I don’t know how you can prefer ‘defer’. It is, in all honestly, a clever but
>> vile and ugly hack. Frankly, a C macro? With a lambda? Using a variable
>> named after the __LINE__ in the code? It’s not reusable, it stays very low
>> level, it’s brittle, hard to write (forget the ; and die). Smart people like
>> Uri had to ask on IRC how it worked and what it was supposed to do…
>> 
> 
> I don't agree with the reuse.
> The __LINE__ is to avoid duplications, you could pass a unique name if you prefer.
> 
>>> 
>>> Beside that you correctly pointed out that there's a race condition
>>> on cursor thread which could lead the cursor thread to attempt writing
>>> the cursor shape before the device is open and you proposed some fixes
>>> in a different series.
>>> I think would be a better fix for this.
>> 
>> But it follows this patch and requires it.
>> 
> 
> Then propose a correct series. Has been pending for more or less 3 months,
> we can't wait ages for a perfect solution and between this patch and the
> defer one I prefer the last.

I believe the last series I sent is closer to a “correct series”. My desire to proceed
in that direction is one of the reasons I had not updated my previous attempt.
The fact that the code was moving fact and causing a lot of churn another.
And the work load related to conferences the final straw on the camel’s back.


Thanks
Christophe

> 
>>> 
>>>> ---
>>>> src/spice-streaming-agent.cpp | 32 ++++++++++++++++++++------------
>>>> 1 file changed, 20 insertions(+), 12 deletions(-)
>>>> 
>>>> diff --git a/src/spice-streaming-agent.cpp b/src/spice-streaming-agent.cpp
>>>> index 25a38a6..e9ef310 100644
>>>> --- a/src/spice-streaming-agent.cpp
>>>> +++ b/src/spice-streaming-agent.cpp
>>>> @@ -53,6 +53,23 @@ struct SpiceStreamDataMessage
>>>>    StreamMsgData msg;
>>>> };
>>>> 
>>>> +struct Stream
>>>> +{
>>>> +    Stream(const char *name, int &fd): fd(fd)
>>>> +    {
>>>> +        fd = open(name, O_RDWR);
>>>> +        if (fd < 0)
>>>> +            throw std::runtime_error("failed to open streaming device");
>>>> +    }
>>>> +    ~Stream()
>>>> +    {
>>>> +        if (fd >= 0)
>>>> +            close(fd);
>>>> +        fd = -1;
>>>> +    }
>>>> +    int &fd;
>>>> +};
>>>> +
>>>> static bool streaming_requested = false;
>>>> static bool quit_requested = false;
>>>> static bool log_binary = false;
>>>> @@ -354,17 +371,14 @@ static void cursor_changes(Display *display, int
>>>> event_base)
>>>> static void
>>>> do_capture(const char *streamport, FILE *f_log)
>>>> {
>>>> -    streamfd = open(streamport.c_str(), O_RDWR);
>>>> -    if (streamfd < 0)
>>>> -        throw std::runtime_error("failed to open the streaming device ("
>>>> +
>>>> -                                 streamport + "): " + strerror(errno));
>>>> +    Stream stream(streamport, streamfd);
>>>> 
>>>>    unsigned int frame_count = 0;
>>>>    while (!quit_requested) {
>>>>        while (!quit_requested && !streaming_requested) {
>>>>            if (read_command(true) < 0) {
>>>>                syslog(LOG_ERR, "FAILED to read command\n");
>>>> -                goto done;
>>>> +                return;
>>>>            }
>>>>        }
>>>> 
>>>> @@ -422,16 +436,10 @@ do_capture(const char *streamport, FILE *f_log)
>>>>            //usleep(1);
>>>>            if (read_command(false) < 0) {
>>>>                syslog(LOG_ERR, "FAILED to read command\n");
>>>> -                goto done;
>>>> +                return;
>>>>            }
>>>>        }
>>>>    }
>>>> -
>>>> -done:
>>>> -    if (streamfd >= 0) {
>>>> -        close(streamfd);
>>>> -        streamfd = -1;
>>>> -    }
>>>> }
>>>> 
>>>> #define arg_error(...) syslog(LOG_ERR, ## __VA_ARGS__);
>>> 
> 
> Frediano



More information about the Spice-devel mailing list