<div dir="ltr">Hi!<div><br></div><div>In our application we assume that dispatch_semaphore_wait(sema, DISPATCH_TIME_NOW) will never block, but recently we found it waiting on OS semaphore.</div><div><br></div><div>Checking source of libdispatch (we used version 215, but the latest available 339.90.1 seems similar) we found the following scenario that could lead to blocking.</div>
<div><br></div><div>Thread1:</div><div>  dispatch_semaphore_wait(sema, DISPATCH_TIME_NOW);</div><div><br></div><div>Thread2:</div><div>  dispatch_semaphore_signal(sema);</div><div>  dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);</div>
<div><br></div><div>Initial state: dsema_value = 0, internal OS semaphore count = 0</div><div><br></div><div>1. Thread 1 enters dispatch_semaphore_wait() and decrements dsema_value -&gt; -1, it&#39;s &lt; 0, so going slow path.</div>
<div><br></div><div>2. Thread 2 signals semaphore, dsema_value incremented from -1 to 0, also going slow path and signals OS semaphore, incrementing its count from 0 to 1.<br></div><div><br></div><div>3. Thread 1 enters DISPATCH_TIME_NOW case in switch in dispatch_semaphore_wait_slow(), but since dsema_value == 0 falls through to DISPATCH_TIME_FOREVER case.<br>
</div><div><br></div><div>4. Thread 2 enters dispatch_semaphore_wait, decrements dsema_value from 0 to -1, goes slow path, waits on OS semaphore, decrements its count back to 0 and exits dispatch_semaphore_wait()</div><div>
<br></div><div>5. Thread 1 waits forever on OS semaphore.</div><div><br></div><div>Interesting that simple test that we wrote to expose that race can easily show it on Linux (e.g. need 1-5 runs). More runs are needed to see it on Solaris (~5-10 runs).</div>
<div>But we failed to make it hung on OS X (10.9.3)</div><div>Is there some changes that are not included in open source libdispatch?</div><div><br></div><div>Please check if our analysis is correct.</div><div>Thanks!</div>
</div>