Exemple #1
0
void AsyncPipeWriter::handleWrite() {
  DestructorGuard dg(this);
  assert(!queue_.empty());
  do {
    auto& front = queue_.front();
    folly::IOBufQueue& curQueue = front.first;
    DCHECK(!curQueue.empty());
    // someday, support writev.  The logic for partial writes is a bit complex
    const IOBuf* head = curQueue.front();
    CHECK(head->length());
#if _WIN32
    // On Windows you can't call write on a socket.
    ssize_t rc = folly::fileutil_detail::wrapNoInt(
        send_internal, fd_, head->data(), head->length());
#else
    ssize_t rc = folly::writeNoInt(fd_.toFd(), head->data(), head->length());
#endif
    if (rc < 0) {
      if (errno == EAGAIN || errno == EWOULDBLOCK) {
        // pipe is full
        VLOG(5) << "write blocked";
        registerHandler(EventHandler::WRITE);
        return;
      } else {
        failAllWrites(AsyncSocketException(
            AsyncSocketException::INTERNAL_ERROR, "write failed", errno));
        closeNow();
        return;
      }
    } else if (rc == 0) {
      registerHandler(EventHandler::WRITE);
      return;
    }
    curQueue.trimStart(size_t(rc));
    if (curQueue.empty()) {
      auto cb = front.second;
      queue_.pop_front();
      if (cb) {
        cb->writeSuccess();
      }
    } else {
      VLOG(5) << "partial write blocked";
    }
  } while (!queue_.empty());

  if (closeOnEmpty_) {
    closeNow();
  } else {
    unregisterHandler();
  }
}
Exemple #2
0
void AsyncPipeWriter::closeOnEmpty() {
  VLOG(5) << "close on empty";
  if (queue_.empty()) {
    closeNow();
  } else {
    closeOnEmpty_ = true;
    CHECK(isHandlerRegistered());
  }
}
Exemple #3
0
void DccTransferRecvWriteCacheHandler::slotKIOResult( KIO::Job* job )
{
    Q_ASSERT( m_transferJob );

    disconnect( m_transferJob, 0, 0, 0 );
    m_transferJob = 0;

    if ( job->error() )
    {
        QString errorString = job->errorString();
        closeNow();
        emit gotError( errorString );             // -> DccTransferRecv::slotLocalGotWriteError()
    }
}
Exemple #4
0
void Cpp2Channel::destroy() {
  closeNow();
  MessageChannel::destroy();
}
Exemple #5
0
 ~ALSADevice()
 {
     closeNow();
 }
void HTTPClientChannel::destroy() {
  closeNow();
  folly::DelayedDestruction::destroy();
}
Exemple #7
0
void Cpp2Channel::readDataAvailable(size_t len) noexcept {
  assert(recvCallback_);
  assert(len > 0);

  DestructorGuard dg(this);

  queue_->postallocate(len);

  if (recvCallback_ && recvCallback_->shouldSample() && !sample_) {
    sample_.reset(new RecvCallback::sample);
    sample_->readBegin = Util::currentTimeUsec();
  }

  // Remaining for this packet.  Will update the class member
  // variable below for the next call to getReadBuffer
  size_t remaining = 0;

  // Loop as long as there are complete (decrypted and deframed) frames.
  // Partial frames are stored inside the handlers between calls to
  // readDataAvailable.
  // On the last iteration, remaining_ is updated to the anticipated remaining
  // frame length (if we're in the middle of a frame) or to readBufferSize_
  // (if we are exactly between frames)
  while (true) {
    unique_ptr<IOBuf> unframed;

    auto ex = folly::try_and_catch<std::exception>([&]() {
      IOBufQueue* decrypted;
      size_t rem = 0;
      std::tie(decrypted, rem) = protectionHandler_->decrypt(queue_.get());

      if (!decrypted) {
        // no full message available, remember how many more bytes we need
        // and continue to frame decoding (because frame decoder might have
        // cached messages)
        remaining = rem;
      }

      // message decrypted
      std::tie(unframed, rem) = framingHandler_->removeFrame(decrypted);

      if (!unframed && remaining == 0) {
        // no full message available, update remaining but only if previous
        // handler (encryption) hasn't already provided a value
        remaining = rem;
      }
    });
    if (ex) {
      if (recvCallback_) {
        VLOG(5) << "Failed to read a message header";
        recvCallback_->messageReceiveErrorWrapped(std::move(ex));
      } else {
        LOG(ERROR) << "Failed to read a message header";
      }
      closeNow();
      return;
    }

    if (!unframed) {
      // no more data
      remaining_ = remaining > 0 ? remaining : readBufferSize_;
      return;
    }

    if (!recvCallback_) {
      LOG(ERROR) << "Received a message, but no recvCallback_ installed!";
      continue;
    }

    if (sample_) {
      sample_->readEnd = Util::currentTimeUsec();
    }
    recvCallback_->messageReceived(std::move(unframed), std::move(sample_));
    if (closing_) {
      return; // don't call more callbacks if we are going to be destroyed
    }
  }
}
Exemple #8
0
void Cpp2Channel::readDataAvailable(size_t len) noexcept {
  assert(recvCallback_);
  assert(len > 0);

  DestructorGuard dg(this);

  queue_->postallocate(len);

  if (recvCallback_ && recvCallback_->shouldSample() && !sample_) {
    sample_.reset(new RecvCallback::sample);
    sample_->readBegin = Util::currentTimeUsec();
  }

  // Remaining for this packet.  Will update the class member
  // variable below for the next call to getReadBuffer
  size_t remaining = 0;

  while (true) {
    unique_ptr<IOBuf> unframed;

    try {
      if (protectionState_ == ProtectionState::INVALID) {
        throw TTransportException("protection state is invalid");
      }

      // If we have a full frame already in a queue ready to go, use
      // it.

      if (protectionState_ != ProtectionState::VALID && queue_->front()) {
        unframed = removeFrame(queue_.get(), remaining);
      } else if (protectionState_ == ProtectionState::VALID &&
                 pendingPlaintext_->front()) {
        unframed = removeFrame(pendingPlaintext_.get(), remaining);
      }
      // We should either get a buffer back, or a remaining indicator.
      // Never both.  Neither is possible, if the length of the framed
      // data is zero.
      assert(!(unframed && remaining > 0));

      // If there wasn't a full message available and we have a
      // protection layer, attempt to unwrap the next piece of
      // ciphertext.
      if (!unframed && protectionState_ == ProtectionState::VALID &&
          queue_->front()) {
        assert(saslEndpoint_ != NULL);
        unique_ptr<IOBuf> unwrapped =
          saslEndpoint_->unwrap(queue_.get(), &remaining);
        assert(!(unwrapped && remaining > 0));
        if (unwrapped) {
          pendingPlaintext_->append(std::move(unwrapped));
          // Start again from the top.
          continue;
        }
      }
    } catch (const std::exception& e) {
      if (recvCallback_) {
        VLOG(5) << "Failed to read a message header";
        recvCallback_->messageReceiveError(std::current_exception());
      } else {
        LOG(ERROR) << "Failed to read a message header";
      }
      closeNow();
      return;
    }

    if (remaining > 0) {
      this->remaining_ = remaining;
      return;
    }

    if (!unframed) {
      break;
    }

    if (!recvCallback_) {
      LOG(ERROR) << "Received a message, but no recvCallback_ installed!";
      continue;
    }

    if (sample_) {
      sample_->readEnd = Util::currentTimeUsec();
    }
    recvCallback_->messageReceived(std::move(unframed), std::move(sample_));
    if (closing_) {
      return; // don't call more callbacks if we are going to be destroyed
    }
  }

  this->remaining_ = 2048;
}
Exemple #9
0
DccTransferRecvWriteCacheHandler::~DccTransferRecvWriteCacheHandler()
{
    closeNow();
}
void MockMcClientTransport::close() {
  closeNow();
}