title: Why would pthread_mutex_lock() hang if pthread_mutex_unlock() has been called?
body: <p>I am using a Swift library for mutable observables that uses a mutex to control reads/writes of the observable value, like so:</p>
  
  <pre class="lang-swift prettyprint-override"><code>import Foundation
  
  class MutObservable&lt;T&gt; {
  
      lazy var m: pthread_mutex_t = {
          var m = pthread_mutex_t()
          pthread_mutex_init(&amp;m, nil)
          return m
      }()
  
      var value: T {
          get {
              return _value
          }
          set {
              pthread_mutex_lock(&amp;m)
              _value = newValue
              pthread_mutex_unlock(&amp;m)
          }
      }
  
  }
  </code></pre>
  
  <p>I'm experiencing a deadlock with this code.  By inserting breakpoints and stepping through, I observe the following:</p>
  
  <ol>
  <li><code>pthread_mutex_lock(&amp;m)</code></li>
  <li><code>pthread_mutex_unlock(&amp;m)</code></li>
  <li><code>pthread_mutex_lock(&amp;m)</code></li>
  <li><code>pthread_mutex_unlock(&amp;m)</code></li>
  <li><code>pthread_mutex_lock(&amp;m)</code> <strong>deadlock</strong></li>
  </ol>
  
  <p>This happens every time this code sequence runs, at least the 30+ times I have tried it.  Two lock/unlock sequences, then a deadlock.</p>
  
  <p>Based on my experience with mutexes in other languages, (Go) I would not expect equal lock/unlock calls to produce a deadlock, but I gather that this is a straight C mutex, so there may be rules here I am not familiar with.  There could also be Swift/C interop factors in the mix.</p>
  
  <p>My best guess is that this is some kind of memory issue, i.e. the lock is being deallocated somehow, but the deadlock is occurring literally <em>in a setter</em> of the object which I believe the owns the lock from a memory perspective, so I'm not sure how that would be the case.</p>
  
  <p>Is there a reason why a <code>pthread_mutex_lock()</code> call would deadlock if the mutex in question has been previously locked and then unlocked?</p>