 
   let leftHandler = leftChannel._onValue(executor: .immediate) { [weak resultChannel] leftValue in
     guard let resultChannel = resultChannel else { return }
+    sema.wait()
+    defer { sema.signal() }
     leftQueue.push(leftValue)
     if let element = makeElement(leftQueue, rightQueue) {
       resultChannel.send(element)

  let resultChannel = Producer<(T, U)>()
  let leftQueue = QueueImpl<T>()
  let rightQueue = QueueImpl<U>()

  func makeElement(_ leftQueue: QueueImpl<T>, _ rightQueue: QueueImpl<U>) -> (T, U)? {
    if leftQueue.isEmpty || rightQueue.isEmpty {


  let rightHandler = rightChannel._onValue(executor: .immediate) { [weak resultChannel] rightValue in
    guard let resultChannel = resultChannel else { return }
    sema.wait()
    defer { sema.signal() }
    rightQueue.push(rightValue)
    if let element = makeElement(leftQueue, rightQueue) {
      resultChannel.send(element)
