bool response_impl::get(data_container* data) { boost::mutex::scoped_lock lock(mutex_); // no more chunks? if (message_finished_ && chunks_.size() == 0) { if (!caught_error_) { return false; } } // block until received callback if (!message_finished_) { while (!response_finished_ && !message_finished_) { cond_var_.wait(lock); } if (!message_finished_) { response_finished_ = false; } } else { if (chunks_.size() > 0) { *data = chunks_.at(0); chunks_.erase(chunks_.begin()); return true; } else { message_finished_ = true; if (caught_error_) { caught_error_ = false; throw dealer_error(static_cast<cocaine::dealer::error_code>(resp_info_.code), resp_info_.error_msg); } return false; } } // expecting another chunk if (chunks_.size() > 0) { *data = chunks_.at(0); chunks_.erase(chunks_.begin()); return true; } if (caught_error_) { caught_error_ = false; throw dealer_error(static_cast<cocaine::dealer::error_code>(resp_info_.code), resp_info_.error_msg); } message_finished_ = true; return false; }
cached_response::cached_response(const std::string& uuid, const message_path& path, const void* data, size_t data_size) : uuid_(uuid), path_(path), code_(0) { if (data_size > MAX_RESPONSE_DATA_SIZE) { throw dealer_error(resource_error, "can't create response, response data too big."); } data_ = data_container(data, data_size); }
bool get_chunk(data_container* data) { // process received chunks if (m_chunks.empty()) { return false; } std::list<boost::shared_ptr<response_chunk_t> >::iterator it; it = m_chunks.begin(); if ((*it)->rpc_code != SERVER_RPC_MESSAGE_ERROR) { *data = (*it)->data; (*it)->data.clear(); m_chunks.erase(it); return true; } else { m_message_finished = true; throw dealer_error(static_cast<cocaine::dealer::error_code>((*it)->error_code), (*it)->error_message); } }