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

Re: [Xen-devel] [PATCH v2 for-4.6 3/3] tools/libxl: Only continue stream operations if the stream is still in progress



On 28/07/15 16:59, Ian Jackson wrote:
> Andrew Cooper writes ("Re: [PATCH v2 for-4.6 3/3] tools/libxl: Only continue 
> stream operations if the stream is still in progress"):
>> On 28/07/15 16:12, Ian Jackson wrote:
>>> What do you think about putting the inuse check in stream_continue ?
>> That would work on the stream_read side but not the stream_write side,
>> but is not really correct IMO.
> I have reread the code on the write side and I think I agree with you
> there.  The next function to be called is write_toolstack_record so
> things are a lot less abstract.
>
> On the read side I looked at a lot of functions which contained:
>
>       stream_continue(egc, stream);
>       return;
>
>    err:
>       assert(rc);
>       stream_complete(egc, stream, rc);
>
> and ISTM that if the analysis leading to these call sites for
> stream_continue is wrong, a similar hazard would exist.

The vast majority of these cases are from internal callbacks.  i.e. they
are within the logical context of the current running stream.

The cases which come in from some external context are
libxl__stream_read_start_checkpoint() and
libxl__xc_domain_restore_done().  The latter is the problem case, while
the former asserts that the stream is in use.

>
>> The _inuse() check is needed because the save helper callback is not
>> sure whether the stream is in use or not.  This is a property of the
>> save helper callback, rather than the stream.
> In this event-driven code, I prefer to have a situation where the next
> thing to do is obvious from the recorded state, and is calculated
> explicitly (see also the way that check_all_finished is now).
>
> This is much less confusing and error prone than code where the next
> thing to do depends on _both_ the recorded state, _and_ the call path
> (representing the most recent thing that happened).

This point is specifically a join point of the end of one asynchronous
task, to another which is expected to be active and running.

It is logically different to the other cases where stream_continue() is
used.

>
>> Pushing the _inuse() check into the next layer would function, but it
>> adds extra _inuse() checks to other codepaths which should be fatal if
>> they failed in other contexts.
> I don't understand how an _inuse check in stream_continue could ever
> do the wrong thing.  If the code is reorganised later, it seems more
> likely to me that there will introduced new situations where we need
> to do "see if we are still running, and if so do stream_continue,
> otherwise go to check_all_finished".

check_all_finished() must only ever be called once for each started
task.  Having

if ( inuse )
    continue()
else
    check_all_finished()

will make it far more likely to accidentally fire the overall stream
callback twice.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.