Linked by Hadrien Grasland on Fri 27th May 2011 11:34 UTC
General Development After having an interesting discussion with Brendan on the topic of deadlocks in threaded and asynchronous event handling systems (see the comments on this blog post), I just had something to ask to the developers on OSnews: could you live without blocking API calls? Could you work with APIs where lengthy tasks like writing to a file, sending a signal, doing network I/O, etc is done in a nonblocking fashion, with only callbacks as a mechanism to return results and notify your software when an operation is done?
Permalink for comment 474828
To read all comments associated with this story, please click here.
IO calls never need to block.
by Alfman on Fri 27th May 2011 15:42 UTC
Alfman
Member since:
2011-01-28

I don't really want to repeat what has already been discussed on the very recent threads about interrupts.

The question doesn't specifically address the deadlock concern in the blog post however, which is acquiring a lock before some call, and then holding it until after the call completes.

Call stack:

driver A (locks mutex a)
- driver B (locks mutex b)
-- driver C
--- driver D
---- driver A (deadlocks on mutex a)


We could detect the circular deadlock/livelock condition and attempt to recover. This is not really trivial. If the OS could infer which threads owned which mutexes, then it could theoretically raise an exception on the call which is responsible for the deadlock condition (so that the second mutex acquire of a could fail, and the second instance of A could return an error).

In reality though, the OS does not know which thread holds a lock since the application may legitimately have passed it to another thread, making it possible for another non-blocked thread to come in an unlock the mutex - it is program specific knowledge.

We could try various things like timing out a mutex acquire (in 2nd instance of A), but this results in unexpected delays and/or failures for the user.

Solutions:
1. We accept that A and B cannot be called recursively, and leave it to the individual drivers to enforce.

2. We add some kind of program specific recursion detection mechanism and return an explicit error.

3. Make A and B re-entrant. Modify the algorithms in A and B to work without a mutex (or at least no mutex across calls to other drivers).

4. We convert the calls to A and B to become queued requests + callbacks (async).

Reply Score: 2