title: Why does dispatch_semaphore_wait() return YES all the time even when I'm not scrolling?
body: <p>Brad Larson delivered a <a href="https://stackoverflow.com/questions/5944050/cadisplaylink-opengl-rendering-breaks-uiscrollview-behaviour">solution</a> for the <code>CADisplayLink</code> freeze issue when scroll views are scrolling.</p>
  
  <p>My OpenGL ES draw method is called by a <code>CADisplayLink</code>, and I tried Brad's technique but can't make it work. The core problem is that my OpenGL ES view is hosted by a <code>UIScrollView</code>, and when the U<code>IScrollView</code> scrolls, the <code>CADisplayLink</code> stops firing.</p>
  
  <p>The technique Brad described is supposed to let the <code>CADisplayLink</code> continue to fire even during scrolling (by adding it to <code>NSRunLoopCommonModes</code> instead of the default runloop mode), and using a fancy semaphore trick the rendering callback is supposed to ensure that it doesn't render when UIKit is too occupied.</p>
  
  <p>The problem is though that the semaphore trick prevents the rendering callback from drawing, no matter what. </p>
  
  <p>First, I create the serial GCD queue and semaphore in the <code>initWithFrame</code> method of my OpenGL ES view like this (on the main thread):</p>
  
  <pre><code>frameRenderingQueue = dispatch_queue_create("com.mycompany.crw", DISPATCH_QUEUE_SERIAL);
  frameRenderingSemaphore = dispatch_semaphore_create(1);
  </code></pre>
  
  <p>The display link is created and added to <code>NSRunLoopCommonModes</code>:</p>
  
  <pre><code>CADisplayLink *dl = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(renderFrame)];
  [dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
  </code></pre>
  
  <p>The render callback performs Brad's technique:</p>
  
  <pre><code>- (void)renderFrame {
      if (dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_NOW) != 0) {
          NSLog(@"return"); // Gets called ALWAYS!
          return;
      }
  
      dispatch_async(drawingQueue, ^{
          @autoreleasepool {
  
              // OpenGL ES drawing code
  
              dispatch_semaphore_signal(frameRenderingSemaphore);
          }
      });
  }
  </code></pre>
  
  <p>The <code>dispatch_semaphore_wait</code> function always returns <code>YES</code> and thus the render callback never renders. Even when I'm not scrolling.</p>
  
  <p>I suppose that I missed something important here. Can someone point it out?</p>
  
  <p>Edit: It seems to work only when I call <code>dispatch_sync</code> instead of <code>dispatch_async</code>, but according to Brad <code>dispatch_async</code> would give better performance here.</p>