hmlongco / Resolver

Swift Ultralight Dependency Injection / Service Locator framework
MIT License
2.14k stars 187 forks source link

Occasional deadlock in multithreading app #174

Closed Kevinvandenhoek closed 1 year ago

Kevinvandenhoek commented 1 year ago

Hi,

I realise you are no longer maintaining this library, so I'm fine with the bug not being solved, but I'm looking for some advise/expertise on this topic:

Sometimes I get a deadlock in one of the resolve calls. Running the app I typically don't see them, but sometimes in the unit tests it does happen. The relevant thread will hang (in this case the main thread), but there are quite a few background threads in the app that also possibly will resolve dependencies. Recently while making some seemingly innocent changes I started seeing fairly consistent deadlocks (in the same resolve call) while running (starting) the app. I was able to work around them by doing some nasty delays, but of course I would really like to know what the proper solution would be or what it is possibly caused by.

My question is: Since this lock is being locked and unlocked all internally in the resolver library, is this deadlock an issue in the library, or could i externally trigger this deadlock? If so, I'm wondering how theoretically deadlocks could be triggered by the app in the library so that I know what I need to look out for in my multithreading code. Attached an image of the stack trace. image of deadlock

Thanks!

Kevinvandenhoek commented 1 year ago

After some digging I found the issue: I was using DispatchQueue.sync to go back to the main thread from one of the initializers of one of my services (with a check to only sync if it was not the main thread already). However, the main thread was waiting on the lock somewhere in resolver, so this caused the deadlock as the initializer was waiting for the main thread, and the main thread was waiting for the initializer running on the background thread to resolve.

hmlongco commented 1 year ago

Glad you found the problem.