<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 12, 2017, at 2:19 AM, Pierre Habouzit via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><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; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class="">On Sep 11, 2017, at 9:00 PM, Chris Lattner via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">On Sep 4, 2017, at 12:18 PM, Pierre Habouzit &lt;<a href="mailto:phabouzit@apple.com" class="">phabouzit@apple.com</a>&gt; wrote:<br class=""><div class=""><blockquote type="cite" class="">Something else I realized, is that this code is fundamentally broken in swift:<br class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space;"><div class=""><div class=""><br class=""></div></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class="">actor func foo()</div></div><div class=""><div class="">{</div></div><div class=""><div class="">&nbsp; &nbsp; NSLock *lock = NSLock();</div></div><div class=""><div class="">&nbsp; &nbsp; lock.lock();</div></div><div class=""><div class=""><br class=""></div></div><div class=""><div class="">&nbsp; &nbsp; let compute = await someCompute(); &lt;--- this will really break `foo` in two pieces of code that can execute on two different physical threads.</div></div><div class=""><div class="">&nbsp; &nbsp; lock.unlock();</div></div><div class=""><div class="">}</div></div></blockquote><div class=""><div class=""><br class=""></div><div class=""><br class=""></div><div class="">The reason why it is broken is that mutexes (whether it's NSLock, pthread_mutex, os_unfair_lock) have to be unlocked from the same thread that took it. the await right in the middle here means that we can't guarantee it.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">Agreed, this is just as broken as:</div><div class=""><br class=""></div><div class="">func foo()<br class="">{<br class="">&nbsp; &nbsp; let lock = NSLock()<br class="">&nbsp; &nbsp; lock.lock()<br class=""><br class="">&nbsp; &nbsp; someCompute {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>&nbsp; &nbsp; lock.unlock()</div><div class="">&nbsp; &nbsp; }<br class="">}</div><div class=""><br class=""></div><div class="">and it is just as broken as trying to do the same thing across queues. &nbsp;Stuff like this, or the use of TLS, is just inherently broken, both with GCD and with any sensible model underlying actors. &nbsp;Trying to fix this is not worth it IMO, it is better to be clear that they are different things and that (as a programmer) you should *expect* your tasks to run on multiple kernel threads.</div><div class=""><br class=""></div><div class="">BTW, why are you using a lock in a single threaded context in the first place??? ;-)</div></div></div></div></blockquote><div class=""><br class=""></div>I don't do locks, I do atomics as a living.</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; -webkit-text-stroke-width: 0px;" class=""><br class=""></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; -webkit-text-stroke-width: 0px;" class="">Joke aside, it's easy to write this bug we should try to have the compiler/analyzer help here for these broken patterns.</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; -webkit-text-stroke-width: 0px;" class="">TSD is IMO less of a problem because people using them are aware of their sharp edges. Not so much for locks.</div></div></blockquote><div><br class=""></div>Maybe we could somehow mark a function to cause a warning/error when directly using it from an async function. &nbsp;You'd want to use that on locks, synchronous I/O, probably some other things.</div><div><br class=""></div><div>Trying to hard-enforce it would pretty quickly turn into a big, annoying effects-system problem, where even a program not using async at all would suddenly have to mark a ton of functions as "async-unsafe". &nbsp;I'm not sure this problem is worth that level of intrusion for most programmers. &nbsp;But a soft enforcement, maybe an opt-in one like the Clang static analyzer, could do a lot to prod people in the right direction.</div><div><br class=""></div><div>John.</div></body></html>