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.73k stars 976 forks source link

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

Closed piksel closed 2 years ago

piksel commented 2 years 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 2 years 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 2 years 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 2 years 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 2 years 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. 😎