labath added a comment.

In D121500#3377434 <https://reviews.llvm.org/D121500#3377434>, @JDevlieghere 
wrote:

> In D121500#3377321 <https://reviews.llvm.org/D121500#3377321>, @labath wrote:
>
>> Are you sure we don't want to handle this at a higher level? The way I 
>> understand it, the main reason for the existence of PrintAsync and 
>> StreamAsynchronousIO machinery is to provide precise control about when the 
>> various bits of output get printed. That's why the asynchronous output gets 
>> plumbed through the topmost iohandler and everything. In that setup, I think 
>> the right solution would be to set up some synchronization inside/near the 
>> iohandler object.
>
> Yes, I considered doing the synchronization in the IO handler. We could have 
> the IOHandler class hold onto a mutex. Locking it in `PrintAsync` takes care 
> of the asynchronous output from the event thread. But everyone else is using 
> the `File`, `StreamFile`, `FILE*` or file descriptor directly, so you need to 
> hand out the mutex every time, in order to avoid colliding with the 
> asynchronous output. That's certainly doable, but how long before someone 
> forgets to lock the mutex? The benefit of doing it at a lower level is that 
> as long as you're using the `Stream`, you're (somewhat) safe. Somewhat 
> because you could still run into trouble when doing something that results in 
> multiple calls to `Stream::WriteImpl`. The disadvantage is that we're still 
> in the same boat for whoever is using the other accessors. I guess it's even 
> slightly worse now, because there's no way to get the mutex.

I agree with your analysis. I haven't inspected the callers, but I'd say the 
right solution is to cut down on the number of places that call these 
functions. Most of the time, this is not the right function to call. We could 
try to make that more explicit, by adding some comments, or even reducing the 
scope/visibility of those functions.

>> In D121500#3376501 <https://reviews.llvm.org/D121500#3376501>, @JDevlieghere 
>> wrote:
>>
>>> Yup, that's exactly what I started doing. I'm aware of at least one 
>>> offender (https://reviews.llvm.org/D121502) because I just added that. But 
>>> I'll see if there are other places that can be migrated to use the Stream 
>>> instead of the File.
>>
>> Yeah, and I actually came very close to bringing that up (that it should be 
>> using StreamAsynchronousIO), but the patch was already submitted, and I did 
>> not want to bother with that. But if we're going to start introducing new 
>> concepts to make that work, then my calculus changes...
>
> I don't think this patch and using `StreamAsynchronousIO` for the progress 
> updates is mutually exclusive.

Depends how you look at it. Without StreamAsynchronousIO, this becomes the 
~only way to ensure thread safety. If we move everything to 
StreamAsynchronousIO, then this could still be useful as an extra line of 
defence, but one could also say that the lack of the mutex (and the resulting 
tsan errors) are an extra line of defence against people misusing the output 
streams. I would put myself in the second camp.

(btw, you did not update the setters in Debuggers::Set(Output|Error)File)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D121500/new/

https://reviews.llvm.org/D121500

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to