title: Recursive synchronization using GCD
body: <p>I have some model classes that I need to synchronize. There is a main object of type <code>Library</code> that contains several <code>Album</code> objects (imagine a music library, for example). Both the library and albums support serialization by implementing the <code>NSCoding</code> protocol. I need to synchronize modifications to the library with album modifications and the serialization of both classes, so that I know the updates don’t step on each other’s toes and that I don’t serialize objects in the middle of an update.</p>
  
  <p>I thought I would just pass all the objects a shared dispatch queue, <code>dispatch_async</code> all the setter code and <code>dispatch_sync</code> the getters. This is simple and easy, but it does not work, as the program flow is recursive:</p>
  
  <pre><code>// In the Library class
  - (void) encodeWithCoder: (NSCoder*) encoder
  {
      dispatch_sync(queue, ^{
          [encoder encodeObject:albums forKey:…];
      });
  }
  
  // In the Album class, same queue as above
  - (void) encodeWithCoder: (NSCoder*) encoder
  {
      dispatch_sync(queue, ^{
          [encoder encodeObject:items forKey:…];
      });
  }
  </code></pre>
  
  <p>Now serializing the library triggers the album serialization and since both method use <code>dispatch_sync</code> on the same queue, the code deadlocks. I have seen this pattern somewhere:</p>
  
  <pre><code>- (void) runOnSynchronizationQueue: (dispatch_block_t) block
  {
      if (dispatch_get_current_queue() == queue) {
          block();
      } else {
          dispatch_sync(queue, block);
      }
  }
  </code></pre>
  
  <p>Does it make sense, will it work, is it safe? Is there an easier way to do the synchronization?</p>