Henrik Grubbstr?m (Lysator) @ Pike (-) developers forum wrote:
- Potential deadlocks/data inconsistency.
This could be considered a plus. Properly written thread-safe code, should not be vulnerable to this. So turning off the call_out() intermediary could be considered a relatively robust way to check if your regular code is actually deadlock-free and thread-safe.
I'm not so sure; eg the following will hang: Thread.Mutex mux = Thread.Mutex(); Thread.MutexKey key = mux->lock(); promise->success(x); key = 0;
void got_sucess(mixed x) Thread.Mutex key = mux->lock(); ...
Yes, it would hang. But, as you might have noticed, previously, the Promise module had some of those constructs, like you show above, in it. By optimising those parts, I found that the actual mutex lock should never be across the ->on_success() call, but usually only should extend over the mere setting/testing of a state variable.
By releasing that lock as early as possibly, I both increase parallelism and reduce lock contention, as well as make it impossible to get into the deadlock situation sketched above.
I think, as proficiency with multithreaded/parallel-running code increases, one learns that often using shorter locks is better, and often eliminates the possibility of a deadlock.