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

      }
      else
      {
        if !signalNextWriter()
        {
          if nextget < tail { signalNextReader() }
        }
        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
