예제 #1
0
    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;
    }
예제 #2
0
    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;
    }
예제 #3
0
    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;
    }