void TFramedTransport::flush() { int32_t sz_hbo, sz_nbo; assert(wBufSize_ > sizeof(sz_nbo)); // Slip the frame size into the start of the buffer. sz_hbo = static_cast<uint32_t>(wBase_ - (wBuf_.get() + sizeof(sz_nbo))); sz_nbo = (int32_t)htonl((uint32_t)(sz_hbo)); memcpy(wBuf_.get(), (uint8_t*)&sz_nbo, sizeof(sz_nbo)); if (sz_hbo > 0) { // Note that we reset wBase_ (with a pad for the frame size) // prior to the underlying write to ensure we're in a sane state // (i.e. internal buffer cleaned) if the underlying write throws // up an exception wBase_ = wBuf_.get() + sizeof(sz_nbo); // Write size and frame body. transport_->write(wBuf_.get(), static_cast<uint32_t>(sizeof(sz_nbo)) + sz_hbo); } // Flush the underlying transport. transport_->flush(); // reclaim write buffer if (wBufSize_ > bufReclaimThresh_) { wBufSize_ = DEFAULT_BUFFER_SIZE; wBuf_.reset(new uint8_t[wBufSize_]); setWriteBuffer(wBuf_.get(), wBufSize_); // reset wBase_ with a pad for the frame size int32_t pad = 0; wBase_ = wBuf_.get() + sizeof(pad); } }
void HttpServerTask::fillWriteBuffer() { if (!hasWriteBuffer() && !writeBuffers.empty()) { StringBuffer * buffer = writeBuffers.front(); writeBuffers.pop_front(); setWriteBuffer(buffer); } }
void TBufferedTransport::shrinkWriteBuffer() { if (wBufResetEveryN_ != 0 && wBufResetEveryN_ == ++wBufResetCount_) { wBufResetCount_ = 0; if (wBufSize_ > wBufResetSize_) { uint8_t* new_buf = new uint8_t[wBufResetSize_]; wBuf_.reset(new_buf); wBufSize_ = wBufResetSize_; setWriteBuffer(wBuf_.get(), wBufSize_); } } }
int32_t TConnection::try_write() { int len; uint32_t left; if (wBuf_ == NULL) { if (!oqueue_.empty()) { TClient* call = oqueue_.front(); string *str = call->mutable_buf(); setWriteBuffer(reinterpret_cast<const uint8_t*>(str->data()), str->length()); } else { return -1; } } left = wBufSize_ - wSize_; while (left > 0) { len = ::send(socket_, wBuf_ + wSize_, left, MSG_DONTWAIT | MSG_NOSIGNAL); if (len < 0) { //LOG(WARNING) << __FUNCTION__ << ": write error: " << strerror(errno) << endl; if (errno == EAGAIN || errno == EWOULDBLOCK) { return -1; } if (errno == EINTR) { continue; } //EPIPE, ECONNRESET, ENOTCONN setWriteBuffer(NULL, 0); io_listener_.error_cb_(io_listener_.data_, this, errno); return -1; } wSize_ += len; left = wBufSize_ - wSize_; } io_listener_.send_done_cb_(io_listener_.data_, oqueue_.front()); oqueue_.pop_front(); setWriteBuffer(NULL, 0); return 0; }