<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 <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> 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 <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> 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 <<a href="mailto:phabouzit@apple.com" class="">phabouzit@apple.com</a>> 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=""> NSLock *lock = NSLock();</div></div><div class=""><div class=""> lock.lock();</div></div><div class=""><div class=""><br class=""></div></div><div class=""><div class=""> let compute = await someCompute(); <--- this will really break `foo` in two pieces of code that can execute on two different physical threads.</div></div><div class=""><div class=""> 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=""> let lock = NSLock()<br class=""> lock.lock()<br class=""><br class=""> someCompute {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span> lock.unlock()</div><div class=""> }<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. Stuff like this, or the use of TLS, is just inherently broken, both with GCD and with any sensible model underlying actors. 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. 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". I'm not sure this problem is worth that level of intrusion for most programmers. 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>