ObPacket* ObPacketQueue::pop() { if (head_ == NULL) { return NULL; } ObPacket* packet = head_; ObPacket* ret_packet = NULL; head_ = (ObPacket*)head_->_next; if (head_ == NULL) { tail_ = NULL; } size_ --; int err = ring_buffer_.pop_task(packet); if (err == OB_SUCCESS) { ThreadSpecificBuffer::Buffer* tb = thread_buffer_->get_buffer(); if (tb == NULL) { TBSYS_LOG(ERROR, "get packet thread buffer failed, return NULL"); } else { int64_t total_size = sizeof(ObPacket) + packet->get_packet_buffer()->get_capacity(); char* buf = tb->current(); memcpy(buf, packet, total_size); ret_packet = (ObPacket*)buf; buf += sizeof(ObPacket); ret_packet->set_packet_buffer(buf, packet->get_packet_buffer()->get_capacity()); } } else { TBSYS_LOG(ERROR, "pop task from ring buffer failed, task: %p, err: %d", packet, err); } return ret_packet; }
bool WaitObjectManager::wakeup_wait_object(const int64_t id, tbnet::Packet* response) { bool ret = true; tbsys::CThreadGuard guard(&mutex_); WaitObject* wait_object = NULL; if (wait_objects_map_.get(id, wait_object) != hash::HASH_EXIST) { TBSYS_LOG(INFO, "wait object not found, id: [%ld]", id); } else { if (response != NULL && response->isRegularPacket()) { ObPacket* packet = dynamic_cast<ObPacket*>(response); if (packet != NULL) { int64_t total_size = sizeof(ObPacket) + packet->get_packet_buffer()->get_position(); char* res_buf = wait_object->response_buffer_; memcpy(res_buf, packet, total_size); wait_object->response_ = (ObPacket*)res_buf; res_buf += sizeof(ObPacket); wait_object->response_->set_packet_buffer(res_buf, packet->get_packet_buffer()->get_position()); } else { TBSYS_LOG(WARN, "receive packet is not ObPacket, pcode: %d", response->getPCode()); ret = false; } } // always add the done count wait_object->wakeup(); } return ret; }
int ObPacketQueue::pop_packets(tbnet::Packet** packet_arr, const int64_t ary_size, int64_t& ret_size) { int err = OB_SUCCESS; ThreadSpecificBuffer::Buffer* tb = NULL; ret_size = 0; if (NULL == packet_arr || ary_size <= 0) { TBSYS_LOG(WARN, "invalid param, packet_arr=%p, arr_size=%ld", packet_arr, ary_size); err = OB_ERROR; } else { tb = thread_buffer_->get_buffer(); if (tb == NULL) { TBSYS_LOG(ERROR, "get packet thread buffer failed, return NULL"); err = OB_ERROR; } else { tb->reset(); } } while (OB_SUCCESS == err && ret_size < ary_size) { if (head_ == NULL) { break; } else { ObPacket* packet = head_; int64_t total_size = sizeof(ObPacket) + packet->get_packet_buffer()->get_capacity(); if (tb->remain() < total_size) { if (0 == ret_size) { TBSYS_LOG(ERROR, "the thread buffer is too small, packet_size=%ld, buffer_size=%ld", total_size, tb->remain()); // discard packet ring_buffer_.pop_task(head_); head_ = (ObPacket*) head_->_next; if (head_ == NULL) { tail_ = NULL; } size_ --; err = OB_ERROR; } break; } else { char* buf = tb->current(); memcpy(buf, packet, total_size); packet_arr[ret_size] = (ObPacket*) buf; buf += sizeof(ObPacket); ((ObPacket*) packet_arr[ret_size])->set_packet_buffer(buf, packet->get_packet_buffer()->get_capacity()); // pop from queue head_ = (ObPacket*) head_->_next; if (head_ == NULL) { tail_ = NULL; } size_ --; // pop from ring buffer err = ring_buffer_.pop_task(packet); if (OB_SUCCESS != err) { TBSYS_LOG(ERROR, "failed to pop task, err=%d", err); } tb->advance(total_size); ++ret_size; } } } return err; }