       let element = buffer.advancedBy(Int(head&mask)).move()
       head += 1
 
-      if !signalNextWriter()
-      {
-        if nextget < tail || closed { signalNextReader() }
+      while let writer = writerQueue.dequeue()
+      {
+        switch writer.sem.state
+        {
+        case .Ready:
+          writer.sem.signal()
+          OSSpinLockUnlock(&lock)
+          return element
+
+        case .WaitSelect:
+          if writer.sem.setState(.Select)
+          {
+            nextput += 1
+            writer.sem.selection = writer.sel!
+            writer.sem.signal()
+            OSSpinLockUnlock(&lock)
+            return element
+          }
+
+        default:
+          assertionFailure("Unexpected case \(writer.sem.state.rawValue) in \(__FUNCTION__)")
+        }
+      }
+      while nextget < tail || closed, let reader = readerQueue.dequeue()
+      {
+        switch reader.sem.state
+        {
+        case .Ready:
+          reader.sem.signal()
+          OSSpinLockUnlock(&lock)
+          return element
+
+        case .WaitSelect:
+          if reader.sem.setState(.Select)
+          {
+            nextget += 1
+            reader.sem.selection = reader.sel!
+            reader.sem.signal()
+            OSSpinLockUnlock(&lock)
+            return element
+          }
+
+        default:
+          assertionFailure("Unexpected case \(reader.sem.state.rawValue) in \(__FUNCTION__)")
+        }
       }
       OSSpinLockUnlock(&lock)
       return element

      }
      else
      {
        if !signalNextReader()
        {
          if head+capacity > nextput || closed { signalNextWriter() }
        }
        OSSpinLockUnlock(&lock)
      }


    OSSpinLockLock(&lock)

    if !closed && head+capacity <= nextput
    {
      let threadLock = SemaphorePool.Obtain()
      do {
        writerQueue.enqueue(QueuedSemaphore(threadLock))
        OSSpinLockUnlock(&lock)
        threadLock.wait()
        OSSpinLockLock(&lock)
      } while !closed && head+capacity <= nextput
      SemaphorePool.Return(threadLock)
    }

    if !closed
