-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possibility for a deadlock #29
Comments
Yes, the scenario that you described is completely possible. This is especially true for nesting async/wait. The source code use DispatchSemaphore, and call wait(timeout: . distantFuture), which certainly means this library can result in deadlocks. This problem could be mitigated by overloading another method such await(timeout: DispatchTime) to allow customization on how long should the thread be locked for. |
Hi @gfzabarino, and sorry for the very late. As @langtutheky said, the scenario you described can indeed happened. I don't know how the Javascript or C# runtimes solve this case. The easiest solution is to put a timeout to the the semaphore waiting for this is not really beautiful... |
@yannickl Async/Await can be easily implemented using a single-threaded/non-blocking model at the language level as in the case of Javascript and C#. Whenever an async block is enter, the compiler/interpreter will create an internal serial queue, wrapping each statement until the next "await" into a closure and push it to the queue. It then serially executes each closure, and pass the return value of the last closure to the next one. All of this happens in a single thread without any blocking. This same technique can be applied for Promises and Javascript's Generators. I have seen lots of Promises implementation on iOS, and sadly most of them use multi-threading/blocking model which is totally unnecessary. Promises's API is purely functional, hence, it can easily implement single-threaded/non-blocking model. But Async/Await and Generators introduce special syntax which helps the code to "look and feel" synchronous, which is impossible to implement on a single thread without compiler/interpreter's interference. Until Async/Await is implemented, probably in Swift 5, there is not much we can do about this issue. With that said, putting a timeout is the best solution right now. Having an overloading await(timeout: DispatchTime) would be nice in cases of long-running task or I/O tasks (downloading/uploading). |
@langtutheky do you have and an example of a library that utilizes single-threaded/non-blocking model? |
Hi! This library looks really great and I'm considering to include it into a new project. However I have a theory question I'd like to get an answer to before doing that. I was wondering if the following scenario was possible:
async
something, which gets executed in the "async" concurrent queue, which runs in thread A.await
for something, which locks thread A, and that something runs on thread B.async
block), but thread A is also awaiting for thread B to resolve its promise. Then there's a deadlock and there's no way of getting out of it.Thank you in advance, and as I'm sure something like StackOverflow would be better to ask this kind of questions, I also know there's no better person to answer it than the creator of the framework himself.
The text was updated successfully, but these errors were encountered: