WaitObject* WaitObjectManager::create_wait_object() { WaitObject* wo = new(std::nothrow) WaitObject(); if (wo != NULL) { // create thread buffer ThreadSpecificBuffer::Buffer* tb = thread_buffer_->get_buffer(); if (tb == NULL || tb->used() > 0) { TBSYS_LOG(ERROR, "get waitobject packet thread buffer failed, buffer %p, used: %d", tb, NULL == tb ? 0 : tb->used()); } else { char* buf = tb->current(); wo->response_buffer_ = buf; if (!insert_wait_object(wo)) { delete wo; wo = NULL; TBSYS_LOG(ERROR, "add waitobject into list failed"); } else { tb->advance(THREAD_BUFFER_ADVANCE_SIZE); } } } return wo; }
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; }