icsharpcode / SharpZipLib

#ziplib is a Zip, GZip, Tar and BZip2 library written entirely in C# for the .NET platform.
http://icsharpcode.github.io/SharpZipLib/
MIT License
3.71k stars 978 forks source link

TarInputStream does not run synchronously when used non-async #788

Closed piksel closed 1 year ago

piksel commented 1 year ago

This is a follow up from #786.

TarInputStream.GetNextEntry() seems to use the thread pool to run "asynchronously", even though it should be fully sync. The async implementation takes an isAsync argument that should make it run totally synchronous when passed with false.

As of #787, deadlocks are avoided using .ConfigureAwait(false), but there is still a bug somewhere that caused this to happen in the first place.

flensrocker commented 1 year ago

https://sharplab.io/ is a good place to see the generated Async-StateMachine. It's just a bit of work to get all the relevant classes into one file to get an overview.

flensrocker commented 1 year ago

I copied all relevant classes used by TarInputStream into one file and added the output from sharplab.io.

If someone wants to take a look... I don't know, when I have the time for it.

TarInputStream-SharpLabIo.zip

piksel commented 1 year ago

Just for reference, this is how a "async with isAsync" method should work: https://sharplab.io/#v2:CYLg1APgAgDABFAjAVgNwFgBQWoGYEBMcAwnAN5ZxUL5QAcCAbADwCWAdgC4B8cAsgAoARgHsRAGzisAzgEFpAT3YBjAJTlK1LawBmcATPlK1GzFvPUoATiYA6ACIBTcQEMFAxDBiqMZi3ABfTQsoAHY4NGDArACgA==

As you can see in the output, the goto just skips the entire state-machine logic and, most importantly, does not call AwaitUnsafeOnCompleted.

flensrocker commented 1 year ago

Found it by stepping through my sample app until the current thread-id switched.

There were two places where a false should be used for the isAsync argument. 😎