       let context = UnsafePointer<T>(dispatch_get_context(ws))
       switch context
       {
-      case nil:
+      case nil, UnsafePointer(cancelSelect):
         preconditionFailure(__FUNCTION__)
 
       default:

        return
      }

      let buffer = UnsafeMutablePointer<T>.alloc(1)
      dispatch_set_context(threadLock, waitSelect)
      self.readerQueue.enqueue(threadLock)
      OSSpinLockUnlock(&self.lock)
      dispatch_semaphore_wait(threadLock, DISPATCH_TIME_FOREVER)

      // got awoken
      let context = dispatch_get_context(threadLock)

      switch context
      {
      case nil:
        // thread was awoken by close(): no more data on the channel
        buffer.dealloc(1)
        if let s = semaphore.get()
        {
          dispatch_set_context(s, nil)
          dispatch_semaphore_signal(s)
        }

      case cancelSelect:
        // no need to try for the semaphore.
        buffer.dealloc(1)

      case buffer:
        let element = buffer.move()
        buffer.dealloc(1)
        if let s = semaphore.get()
        {
          let selection = Selection(selectionID: selectionID, selectionData: element)
          let selectptr = UnsafeMutablePointer<Void>(Unmanaged.passRetained(selection).toOpaque())
          dispatch_set_context(s, selectptr)
          dispatch_semaphore_signal(s)
        }
        else
        { // what to do? We have data, but it has no taker. try to pass it on to another reader.
          self.put(element)
        }

      default:
        buffer.dealloc(1)
        // precondition(false, "Weird semaphore context in \(__FUNCTION__)")
        let selectput = Unmanaged<dispatch_semaphore_t>.fromOpaque(COpaquePointer(context)).takeRetainedValue()
        if let s = semaphore.get()
        {
          let selection = Selection(selectionID: selectionID, selectionData: selectput)
          let selectptr = UnsafeMutablePointer<Void>(Unmanaged.passRetained(selection).toOpaque())
          dispatch_set_context(s, selectptr)
          dispatch_semaphore_signal(s)
        }
        else
        {
          dispatch_set_context(selectput, nil)
          dispatch_semaphore_signal(selectput)
        }

    OSSpinLockLock(&lock)
    if let rs = readerQueue.dequeue()
    {
      if dispatch_get_context(rs) != waitSelect
      {
        OSSpinLockUnlock(&lock)
        return Selection(selectionID: selectionID, selectionData: rs)
      }
      readerQueue.undequeue(rs)
    }
    OSSpinLockUnlock(&lock)
    return nil
  }

  override func selectPut(semaphore: SemaphoreChan, selectionID: Selectable) -> Signal
