<div><div dir="auto">To avoid or at least detect deadlocks you need: timeout (which will at least generate an error), cancel (which will prevent zombie processes), and status information (for debugging). It doesn’t make any difference if the reference is strong or weak. There is an advantage in strong references since you can fire and forget if you want a deamon process that is totally self managing. </div><br><div class="gmail_quote"><div>On Sun, 27 Aug 2017 at 12:53 am, Marc Schlichte via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><blockquote type="cite"><div>Am 26.08.2017 um 02:03 schrieb Adam Kemp via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;:</div><br class="m_8186087962067118274Apple-interchange-newline"><div><div style="word-wrap:break-word;line-break:after-white-space">I’m not sure I understand. What is the connection between references and deadlocks?<br></div></div></blockquote><div><br></div><div><br></div></div></div><div style="word-wrap:break-word"><div><div><div>This is what I had in mind:</div><div><br></div><div>To have a deadlock from async actor methods, you would need some mutual invocations of them - i.e a cycle in the call graph.</div><div><br></div><div>If your code is (strong) retain cycle free and you make invocations only on actors of which you have strong references, you will also have no cyclic call graph, hence no deadlocks.</div><div><br></div><div><br></div><div>Now, unfortunately - and contrary to my claim - deadlocks still can happen:</div><div><br></div><div>if you `await` in your async actor method on some state which can only be set via another actor method in your actor, a deadlock occurs:</div><div><br></div><div>Example:</div><div>```</div><div>actor class A {</div><div>  var continuation: (() -&gt; Void)?</div><div>  actor func m1() async {</div><div>    await suspendAsync { cont in</div><div>      continuation = cont</div><div>    }</div><div>  }</div><div>  actor func m2() {</div><div>    continuation?()</div><div>  }</div><div>}</div><div>```</div><div><br></div><div>If someone calls `a.m1()`, and someone else `a.m2()`, `a.m1()` still does not complete as `a.m2()` is not allowed to run while `a.m1()` is not finished.</div><div><br></div><div>Marking `m2` as an `interleaved actor func` would remedy that situation as it could then run when the next work item is picked from the serial gdc queue - which can happen while we `await` on the `suspendAsync` in the example above. </div><div><br></div><div><br></div>Cheers</div></div></div><div style="word-wrap:break-word"><div><div>Marc</div></div></div><div style="word-wrap:break-word"><div><div><br></div><blockquote type="cite"><div><div style="word-wrap:break-word;line-break:after-white-space"><div><br><blockquote type="cite"><div>On Aug 25, 2017, at 1:07 PM, Marc Schlichte &lt;<a href="mailto:marc.schlichte@googlemail.com" target="_blank">marc.schlichte@googlemail.com</a>&gt; wrote:</div><br class="m_8186087962067118274Apple-interchange-newline"><div><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>Am 25.08.2017 um 19:08 schrieb Adam Kemp via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;:</div><br class="m_8186087962067118274Apple-interchange-newline"><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">I understand what you’re saying, but I just think trying to make synchronous, blocking actor methods goes against the fundamental ideal of the actor model, and it’s a recipe for disaster. When actors communicate with each other that communication needs to be asynchronous or you will get deadlocks. It’s not just going to be a corner case. It’s going to be a very frequent occurrence.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">One of the general rules of multithreaded programming is “don’t call unknown code while holding a lock”. Blocking a queue is effectively the same as holding a lock, and calling another actor is calling unknown code. So if the model works that way then the language itself will be encouraging people to call unknown code while holding locks. That is not going to go well.</div><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important"></span><br class="m_8186087962067118274Apple-interchange-newline"></div></blockquote></div><br><div>I would claim - without having a prove though - that as long as you don’t invoke async actor methods on weak or unowned actor references and the code is retain cycle free, no deadlocks will happen.</div><div><br></div><div>Cheers</div><div>Marc</div><div><br></div></div></div></blockquote></div><br></div>_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div></blockquote></div></div>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div></div><div dir="ltr">-- <br></div><div class="gmail_signature" data-smartmail="gmail_signature">-- Howard.</div>