How to cancel URL::readEntireTextStream()?


#1

After a user has entered his credentials, the OnlineUnlockForm displays a modal overlay with a spinner (OnlineUnlockForm::OverlayComp). I want to add a cancel button to this overlay, because with an aggressive firewall or a not or really slow responding server it can happen that this overlay just stays indefinitely without providing the user an option to escape.

In essence, the OverlayComp is/starts a Thread that calls

url.readEntireTextStream()

via TracktionMarketplaceStatus::readReplyFromWebserver().

How can this url.readEntireTextStream() be properly canceled?

Calling (from within the OverlayComp)

stopThread (0);
delete this;

will leak an URLConnectionState.


#2

Actually, it would be nice to have a cancel button on the OnlineUnlockForm::OverlayComp by default.


#3

I’ve added an optional argument to the OnlineUnlockForm constructor to specify whether the OverlayComp should contain a cancel button. It’s on develop here.


#4

Thanks for adding a cancel button!

I’m not an expert on threads, but with your solution multiple assertions will be hit (maybe this isn’t an issue at all…).

To reproduce

  • Use a tool like Little Snitch on macOS to specifically delay or block the communication from your JUCE application to the unlock server.
  • Start the online unlocking procedure from within the application.
  • Click your new cancel button.

-> assertion in juce_Thread::219

        // very bad karma if this point is reached, as there are bound to be
        // locks and events left in silly states when a thread is killed by force..
  • Quit the application

-> the LeakObjectDetector will detect leaked objects: URLConnectionState, WebInputStream, Pimpl, URL, Thread, WaitableEvent, MemoryBlock, InputStream, StringPairArray and StringArray.

As mentioned in my initial post, most of these leaks are caused by URL::readEntireTextStream().


#5

Yeah, this is more of an issue with the TracktionMarketplaceStatus::readReplyFromWebserver() implementation as it should have a cancellable operation instead of just calling readEntireTextStream(). I’ll take a look at this later today and see if I can replace it with something that exits more gracefully when the thread is stopped.


#6

OK, I’ve just pushed something to develop to make sure that TracktionMarketplaceStatus::readReplyFromWebserver() handles being cancelled properly.


#7

Awesome, thanks a lot @ed95 ! Works great now.

+1 :beer: for you at the ADC17