SendResult_ptr DefaultMQProducerImpl::sendKernelImpl(Message_ptr msg, MessageQueue* mq, std::string& communicationMode, bool sendCallback) {
    std::string brokerAddr = this->mQClientFactory->findBrokerAddressInPublish(mq->getBrokerName());
    if (brokerAddr.empty()) {
        // TODO 此处可能对Name Server压力过大,需要调优
        this->mQClientFactory->updateTopicRouteInfoFromNameServer(mq->getTopic());
        this->mQClientFactory->updateTopicRouteInfoFromNameServer(mq->getTopic(), true, this->defaultMQProducer);
        brokerAddr = this->mQClientFactory->findBrokerAddressInPublish(mq->getBrokerName());
    }

    if (!brokerAddr.empty()) {
        std::string prevBody = msg->getBody();
        int sysFlag = 0;

        SendMessageRequestHeader_var requestHeader = new SendMessageRequestHeader();
        requestHeader->setProducerGroup(this->defaultMQProducer->getProducerGroup());
        requestHeader->setTopic(msg->getTopic());
        requestHeader->setDefaultTopic(this->defaultMQProducer->getCreateTopicKey());
        requestHeader->setDefaultTopicQueueNums(this->defaultMQProducer->getDefaultTopicQueueNums());
        requestHeader->setQueueId(mq->getQueueId());
        requestHeader->setSysFlag(sysFlag);
        requestHeader->setBornTimestamp(112233);
        requestHeader->setFlag(msg->getFlag());

        SendResult_var sendResult = new SendResult();
        this->mQClientFactory->getMQClientAPIImpl()->sendMessage(brokerAddr, mq->getBrokerName(), SendMessageRequestHeader_var::Duplicate(requestHeader), 3);
        return SendResult_var::Duplicate(sendResult);
    }
    return NULL;
}
Exemplo n.º 2
0
  void Acknowledge::send (Message_ptr m)
  {
    if (Data const* data = static_cast<Data const*> (m->find (Data::id)))
    {
      size_t max_payload_size (
        params_.max_packet_size () - max_service_size);

      if (max_payload_size > data->size ())
      {
        u32 max_size (max_payload_size - data->size ());
        u32 max_elem (NRTM::max_count (max_size));

        if (max_elem > 0)
        {
          Lock l (mutex_);

          Profile_ptr nrtm (create_nrtm (max_elem));

          if (nrtm.get ())
            m->add (nrtm);
        }
      }

      nrtm_timer_ = params_.nrtm_timeout (); // Reset timer.
    }

    out_->send (m);
  }
Exemplo n.º 3
0
  void Socket_Impl::
    send_ (void const* buf, size_t s)
    {
      Message_ptr m (new Message);

      m->add (Profile_ptr (new Data (buf, s)));

      // Qualification is for VC6 and VxWorks.
      //
      Element::send (m);
    }
Exemplo n.º 4
0
  void Retransmit::send (Message_ptr m)
  {
    if (m->find (Data::id) != 0)
    {
      SN const* sn = static_cast<SN const*> (m->find (SN::id));

      Lock l (mutex_);
      queue_.bind (sn->num (), Descr (m->clone ()));
    }

    out_->send (m);
  }
Exemplo n.º 5
0
  ssize_t Socket_Impl::
    size_ (ACE_Time_Value const* timeout)
    {
      ACE_Time_Value abs_time;

      if (timeout)
        abs_time = ACE_OS::gettimeofday () + *timeout;

      Lock l (mutex_);

      while (queue_.is_empty ())
        {
          if (timeout)
            {
              if (cond_.wait (&abs_time) != -1)
                break;
            }
          else
            {
              if (cond_.wait () != -1)
                break;
            }

          return -1; // errno is already set
        }

      // I can't get the head of the queue without actually dequeuing
      // the element.
      //
      Message_ptr m;

      if (queue_.dequeue_head (m) == -1)
        ACE_OS::abort ();

      if (queue_.enqueue_head (m) == -1)
        ACE_OS::abort ();

      if (m->find (NoData::id) != 0)
        {
          errno = ENOENT;
          return -1;
        }

      Data const* d = static_cast<Data const*>(m->find (Data::id));

      return static_cast<ssize_t> (d->size ());
    }
Exemplo n.º 6
0
  void Retransmit::recv (Message_ptr m)
  {
    if (NAK const* nak = static_cast<NAK const*> (m->find (NAK::id)))
    {
      Address to (static_cast<To const*> (m->find (To::id))->address ());

      if (nak->address () == to)
      {
        Lock l (mutex_);

        for (NAK::iterator j (const_cast<NAK*> (nak)->begin ());
             !j.done ();
             j.advance ())
        {
          u64* psn;
          j.next (psn);

          Message_ptr m;

          Queue::ENTRY* pair;

          if (queue_.find (*psn, pair) == 0)
          {
            //cerr << 5 << "PRTM " << to << " " << pair->ext_id_ << endl;

            m = pair->int_id_.message ();

            pair->int_id_.reset ();
          }
          else
          {
            //cerr << 4 << "message " << *psn << " not available" << endl;

            m = Message_ptr (new Message);
            m->add (Profile_ptr (new SN (*psn)));
            m->add (Profile_ptr (new NoData));
          }

          out_->send (m);
        }
      }
    }

    in_->recv (m);
  }
Exemplo n.º 7
0
  void Socket_Impl::recv (Message_ptr m)
    {
      if (m->find (Data::id) != 0 || m->find (NoData::id) != 0)
        {
          if (!loop_)
            {
              Address to (static_cast<To const*> (m->find (To::id))->address ());

              Address from (
                            static_cast<From const*> (m->find (From::id))->address ());

              if (to == from)
                return;
            }

          Lock l (mutex_);

          //if (queue_.size () != 0)
          //  cerr << "recv socket queue size: " << queue_.size () << endl;

          //FUZZ: disable check_for_lack_ACE_OS
          bool signal (queue_.is_empty ());
          //FUZZ: enable check_for_lack_ACE_OS

          queue_.enqueue_tail (m);

          if (signal)
            {
              // Also write to the pipe.
              if (signal_pipe_.write_handle () != ACE_INVALID_HANDLE)
                {
                  char c;

                  if (signal_pipe_.send (&c, 1) != 1)
                    {
                      // perror ("write: ");
                      ACE_OS::abort ();
                    }
                }

              cond_.signal ();
            }
        }
    }
Exemplo n.º 8
0
  void Fragment::send (Message_ptr m)
  {
    if (Data const* data = static_cast<Data const*> (m->find (Data::id)))
    {
      size_t max_payload_size (
        params_.max_packet_size () - max_service_size);

      if (data->size () <= max_payload_size)
      {
        u64 sn;
        {
          Lock l (mutex_);
          sn = sn_++;
        }

        m->add (Profile_ptr (new SN (sn)));

        out_->send (m);
        return;
      }

      char const* p = data->buf ();
      size_t size (data->size ());

      // Need fragmentation.
      //
      u32 packets (size / max_payload_size + (size % max_payload_size ? 1 : 0));

      // cerr << "size : " << size << endl
      //      << "packs: " << packets << endl;

      for (u32 i (1); i <= packets; ++i)
      {
        Message_ptr part (new Message);

        size_t s (i == packets ? size % max_payload_size : max_payload_size);

        // cerr << "pack: " << s << endl;

        u64 sn;
        {
          Lock l (mutex_);
          sn = sn_++;
        }

        part->add (Profile_ptr (new SN (sn)));
        part->add (Profile_ptr (new Part (i, packets, size)));
        part->add (Profile_ptr (new Data (p, s)));

        out_->send (part);

        p += s;
      }
    }
  }
Exemplo n.º 9
0
void MessageProcessorManager::processMessage(
        Connection_ptr con,
        Message_ptr msg)
{
    // Obtiene el contenido y el descriptor del mensaje
    Holder holder = msg->holder();
    TypeDescriptor_ptr messageDescriptor = 
        holder.get_type_descriptor();

    // creates the key
    map_t::iterator it = m_processors.find(
            std::make_pair(con.get(), messageDescriptor));

    if (it != m_processors.end() && 
            !it->second.empty())
    {
        // Iterates over its associated processors
        processors_t::const_iterator pit = it->second.begin(); 

        for (; pit != it->second.end(); ++pit) 
        {
            const MessageProcessor_ptr processor = *pit;
            const ReflectivePath_t& path = processor->path();

            // Results
            TypeDescriptor_ptr descriptor = NULL;
            Holder value;

            bool res = followPath(messageDescriptor, holder, path, 
                    // Results
                    descriptor, value);

            if (res)
                processor->process(msg, value);
        }
    }
}
SendResult_ptr DefaultMQProducerImpl::sendDefaultImpl(Message_ptr msg, std::string& communicationMode, bool sendCallback) {
    long beginTimestamp = 0;
    long endTimestamp = beginTimestamp;
    TopicPublishInfo* topicPublishInfo = this->tryToFindTopicPublishInfo(msg->getTopic());
    if (topicPublishInfo->ok()) {
        MessageQueue* mq = NULL;
        SendResult_var sendResult = new SendResult();
        for (int times = 0; times < 3; times++) {
            std::string lastBrokerName;
            if(mq != NULL) {
                lastBrokerName = mq->getBrokerName();
            }
            MessageQueue* tmpmq = topicPublishInfo->selectOneMessageQueue(lastBrokerName);
            if (tmpmq != NULL) {
                mq = tmpmq;
                sendResult = this->sendKernelImpl(msg, mq, communicationMode, sendCallback);
                endTimestamp = 12;
                if(communicationMode == CommunicationMode::SYNC) {
                    if (sendResult->getSendStatus() != SendStatus::SEND_OK) {
                        /*
                        if (this->defaultMQProducer->isRetryAnotherBrokerWhenNotStoreOK()) {
                        	continue;
                        }
                        */
                    }
                    return SendResult_var::Duplicate(sendResult);
                }
            }
            else {
                break;
            }
        }
        return SendResult_var::Duplicate(sendResult);
    }
    return NULL;
}
Exemplo n.º 11
0
void
ProtocolDataWidget::onRecv(Message_ptr m)
{
        Address from;
        if (From const* f = static_cast<From const*>(m->find(From::id)))
        {
                from = f->address();
        }

        if (PFileSend const* pfs = static_cast<PFileSend const*>(m->find(IMProto::FileSend)))
        {
                QString const& sn = QString::fromUtf8(pfs->property_data(IMProto::EventSn));
                QString const& kName = QString::fromUtf8(pfs->property_data(IMProto::FileKey));
                QString const& fName = QString::fromUtf8(pfs->property_data(IMProto::FileName));
                quint64 siz = QString::fromUtf8(pfs->property_data(IMProto::FileSize)).toULongLong();
                //u16 port = QString::fromUtf8(pfs->property_data(IMProto::ListenPort)).toUShort();

                QTreeWidgetItem* root = new QTreeWidgetItem;
                this->addTopLevelItem(root);
                m_RecvItemMap.insert(sn, root);
                QString const& sizstr = GetFormatedFileSize(siz);

                root->setText(COL_NAME, fName);
                root->setText(COL_SIZE, sizstr);
                root->setText(COL_TYPE, tr("File"));
                root->setText(COL_STATE, tr("waiting to receive"));
                root->setText(COL_PERCENT, "0%");
                root->setData(COL_NAME, FileKeyRole, kName);
                root->setData(COL_NAME, FileSizeRole, siz);
                root->setData(COL_NAME, DirFileRole, "FILE");
                root->setData(COL_NAME, SendRecvRole, "R");
                root->setData(COL_NAME, TransStateRole, "WAIT");
                root->setData(COL_NAME, TransItemSNRole, sn);
                root->setIcon(COL_NAME, QIcon(DataAccess::SkinPath() + "/download-file.png"));
                root->setIcon(COL_STATE, QIcon(DataAccess::SkinPath() + "/clock.png"));
                emit sigTips(tr("The other request to send %1:%2. Please switch to file transferring window to process.")
                        .arg(tr("File"))
                        .arg(fName));
        }
        else if (PDirFileRecv const* pfr = static_cast<PDirFileRecv const*>(m->find(IMProto::DirFileRecv)))
        {
                QString const& sn = QString::fromUtf8(pfr->property_data(IMProto::EventSn));
                QString const& kName = QString::fromUtf8(pfr->property_data(IMProto::FileKey));
                u16 port = QString::fromUtf8(pfr->property_data(IMProto::ListenPort)).toUShort();

                QTreeWidgetItem* item = m_SendItemMap.value(sn, 0);
                if (!item)
                {
                        //QMessageBox::critical(this, tr("Error"), tr("Unable to find item in file SendItemMap. key: %1.").arg(keys[2]));
                        return;
                }
                QString const& pfName = m_userItem->SendingFilesCollection()->value(kName);
                if (pfName.isEmpty())
                {
                        //QMessageBox::critical(this, tr("Error"), tr("Unable to find in SendingFilesCollection key: %1.").arg(keys[2]));
                        return;
                }
                QFileInfo finfo(pfName);

                ProtocolDataTransfer* pdthr = 0;
                if (finfo.isFile())
                {
                        pdthr = new ProtocolDataTransfer(item, pfName, 0,
                                port, m_userItem->IpAddress(),
                                ProtocolDataTransfer::DoSendFile);
                        connect(&m_timer, SIGNAL(timeout()), pdthr, SLOT(slotUpdate()));
                }
                else  if (finfo.isDir())
                {
                        pdthr = new ProtocolDataTransfer(item, pfName,
                                port, m_userItem->IpAddress(),
                                ProtocolDataTransfer::DoSendDir);
                        connect(&m_timer, SIGNAL(timeout()), pdthr, SLOT(slotUpdate()));
                }
                if (!pdthr)
                {
                        return;
                }
                item->setData(COL_NAME, TransThreadRole, (quint64)pdthr);
                if (!m_timer.isActive())
                {
                        m_timer.start(1000);
                }
                pdthr->start();
        } 
        else if (ProfileWithProperties const* pds = static_cast<ProfileWithProperties const*>(m->find(IMProto::DirSend)))
        {
                QString const& sn = QString::fromUtf8(pds->property_data(IMProto::EventSn));
                QString const& kName = QString::fromUtf8(pds->property_data(IMProto::FileKey));
                QString const& dName = QString::fromUtf8(pds->property_data(IMProto::FileName));
                quint64 siz = QString::fromUtf8(pds->property_data(IMProto::FileSize)).toULongLong();
                //u16 port = QString::fromUtf8(pfs->property_data(IMProto::ListenPort)).toUShort();

                QTreeWidgetItem* root = new QTreeWidgetItem;
                this->addTopLevelItem(root);
                m_RecvItemMap.insert(sn, root);
                QString const& sizstr = tr("unknown");

                root->setText(COL_NAME, dName);
                root->setText(COL_SIZE, sizstr);
                root->setText(COL_TYPE, tr("Dir"));
                root->setText(COL_STATE, tr("waiting to receive"));
                root->setText(COL_PERCENT, "0%");
                root->setData(COL_NAME, FileKeyRole, kName);
                root->setData(COL_NAME, FileSizeRole, siz);
                root->setData(COL_NAME, DirFileRole, "DIR");
                root->setData(COL_NAME, SendRecvRole, "R");
                root->setData(COL_NAME, TransStateRole, "WAIT");
                root->setData(COL_NAME, TransItemSNRole, sn);
                root->setIcon(COL_NAME, QIcon(DataAccess::SkinPath() + "/download-folder.png"));
                root->setIcon(COL_STATE, QIcon(DataAccess::SkinPath() + "/clock.png"));
                emit sigTips(tr("The other request to send %1:%2. Please switch to file transferring window to process.")
                        .arg(tr("Dir"))
                        .arg(dName));
        } 
        else if (PDirFileSendCancel const* pfsc = static_cast<PDirFileSendCancel const*>(m->find(IMProto::DirFileSendCancel)))
        {
                QString const& sn = QString::fromUtf8(pfsc->property_data(IMProto::EventSn));
                QTreeWidgetItem* item = m_RecvItemMap.value(sn);
                if (!item)
                {
                        //QMessageBox::critical(this, tr("Error"), tr("Unable to find item in file RecvItemMap. key: %1.").arg(keys[2]));
                        return;
                }
                QString tips = tr("The other canceled sending %1: %2.").arg(item->text(COL_TYPE)).arg(item->text(COL_NAME));
                emit sigTips(tips);
                m_RecvItemMap.remove(sn);

                QString const& tsr = item->data(COL_NAME, TransStateRole).toString();
                if (tsr == "START")
                {
                        ProtocolDataTransfer* t = (ProtocolDataTransfer*)item->data(COL_NAME, TransThreadRole).toULongLong();
                        disconnect(&m_timer, SIGNAL(timeout()), t, SLOT(slotUpdate()));
                        t->slotCancel();
                }

                if (!delItemWhenFinished)
                {
                        item->setData(COL_NAME, TransStateRole, "CANCEL");
                        item->setIcon(COL_STATE, QIcon(DataAccess::SkinPath() + "/warning.png"));
                        item->setText(COL_STATE, tr("Canceled"));
                }
                else
                {
                        this->takeTopLevelItem(this->indexOfTopLevelItem(item));
                }
        } 
        else if (ProfileWithProperties const* pfrc = static_cast<ProfileWithProperties const*>(m->find(IMProto::DirFileRecvCancel)))
        {
                QString const& sn = QString::fromUtf8(pfrc->property_data(IMProto::EventSn));
                QTreeWidgetItem* item = m_SendItemMap.value(sn, 0);
                if (!item)
                {
                        //QMessageBox::critical(this, tr("Error"), tr("Unable to find item in file SendItemMap. key: %1.").arg(keys[2]));
                        return;
                }
                QString tips = tr("The other canceled receiving %1: %2.").arg(item->text(COL_TYPE)).arg(item->text(COL_NAME));
                emit sigTips(tips);
                m_SendItemMap.remove(sn);

                QString const& tsr = item->data(COL_NAME, TransStateRole).toString();
                if (tsr == "START")
                {
                        ProtocolDataTransfer* t = (ProtocolDataTransfer*)item->data(COL_NAME, TransThreadRole).toLongLong();
                        disconnect(&m_timer, SIGNAL(timeout()), t, SLOT(slotUpdate()));
                        t->slotCancel();
                }
                if (!delItemWhenFinished)
                {
                        item->setData(COL_NAME, TransStateRole, "CANCEL");
                        item->setIcon(COL_STATE, QIcon(DataAccess::SkinPath() + "/warning.png"));
                        item->setText(COL_STATE, tr("Canceled"));
                }
                else
                {
                        this->takeTopLevelItem(this->indexOfTopLevelItem(item));
                }
        }
}
Exemplo n.º 12
0
  void Acknowledge::
  track ()
  {
    while (true)
    {
      Messages msgs;

      {
        Lock l (mutex_);

        if (stop_)
          break;

        if (hold_.current_size () != 0)
        {
          for (Map::iterator i (hold_.begin ()), e (hold_.end ());
               i != e;
               ++i)
          {
            Queue& q = (*i).int_id_;

            if (q.current_size () == 0) continue;

            track_queue ((*i).ext_id_, q, msgs);
          }
        }

        if (--nrtm_timer_ == 0)
        {
          nrtm_timer_ = params_.nrtm_timeout ();

          // Send NRTM.
          //
          unsigned short max_payload_size (
            params_.max_packet_size () - max_service_size);

          u32 max_elem (NRTM::max_count (max_payload_size));

          Profile_ptr nrtm (create_nrtm (max_elem));

          if (!nrtm.null ())
          {
            Message_ptr m (new Message);
            m->add (nrtm);
            msgs.push_back (m);

          }
        }
      }

      // Send stuff off.
      //
      for (Messages::Iterator i (msgs); !i.done (); i.advance ())
      {
        Message_ptr* ppm;
        i.next (ppm);

        //FUZZ: disable check_for_lack_ACE_OS
        send (*ppm);
        //FUZZ: enable check_for_lack_ACE_OS
      }

      // Go to sleep but watch for "manual cancellation" request.
      //
      {
        //FUZZ: disable check_for_lack_ACE_OS
        ACE_Time_Value time (ACE_OS::gettimeofday ());
        //FUZZ: enable check_for_lack_ACE_OS

        time += params_.tick ();

        Lock l (mutex_);

        while (!stop_)
        {
          if (cond_.wait (&time) == -1)
          {
            if (errno != ETIME)
              ACE_OS::abort ();
            else
              break;
          }
        }

        if (stop_)
          break;
      }
    }
  }
Exemplo n.º 13
0
  void Acknowledge::recv (Message_ptr m)
  {
    // Handle NRTM. There could be some nasty interaction with code
    // that handles data below (like missing message and NAK). This
    // is why I hold the lock at the beginning (which may be not very
    // efficient).
    //
    Lock l (mutex_);

    if (NRTM const* nrtm = static_cast<NRTM const*> (m->find (NRTM::id)))
    {
      for (Map::iterator i (hold_.begin ()), e (hold_.end ()); i != e; ++i)
      {
        u64 sn (nrtm->find ((*i).ext_id_));

        if (sn != 0)
        {
          Queue& q = (*i).int_id_;

          u64 old (q.max_sn ());

          if (old < sn)
          {
            // Mark as lost.
            //
            q.bind (sn, Descr (1));
          }
        }
      }
    }

    if (m->find (Data::id) || m->find (NoData::id))
    {
      Address from (
        static_cast<From const*> (m->find (From::id))->address ());

      u64 sn (static_cast<SN const*> (m->find (SN::id))->num ());

      Map::ENTRY* e = 0;

      if (hold_.find (from, e) == -1)
      {
        // First message from this source.
        //
        hold_.bind (from, Queue (sn));
        in_->recv (m);
      }
      else
      {
        Queue& q = e->int_id_;

        if (sn <= q.sn ())
        {
          // Duplicate.
          //
          //cerr << 6 << "DUP " << from << " " << q.sn () << " >= " << sn
          //     << endl;
        }
        else if (sn == q.sn () + 1)
        {
          // Next message.
          //

          q.rebind (sn, Descr (m));
          collapse (q);
        }
        else
        {
          // Some messages are missing. Insert this one into the queue.
          //
          q.rebind (sn, Descr (m));
        }
      }
    }
    else
    {
      l.release ();

      // Just forward it up.
      //
      in_->recv (m);
    }
  }
Exemplo n.º 14
0
  void Acknowledge::
  track_queue (Address const& addr, Queue& q, Messages& msgs)
  {
    unsigned short max_payload_size (
      params_.max_packet_size () - max_service_size);

    u32 max_elem (NAK::max_count (max_payload_size));
    u32 count (0);

    Queue::iterator i (q.begin ()), e (q.end ());

    // Track existing losses.
    //
    while (i != e)
    {
      auto_ptr<NAK> nak (new NAK (addr));

      // Inner loop that fills NAK profile with up to max_elem elements.
      //
      for (; i != e && nak->count () < max_elem; ++i)
      {
        u64 sn ((*i).ext_id_);
        Descr& d = (*i).int_id_;

        if (d.lost ())
        {
          d.timer (d.timer () - 1);

          if (d.timer () == 0)
          {
            //@@ Need exp fallback.
            //
            d.nak_count (d.nak_count () + 1);
            d.timer ((d.nak_count () + 1) * params_.nak_timeout ());

            nak->add (sn);

            ++count;

            // cerr << 6 << "NAK # " << d.nak_count () << ": "
            // << addr << " " << sn << endl;
          }
        }
      }

      // Send this NAK.
      //
      if (nak->count ())
      {
        // cerr << 5 << "NAK: " << addr << " " << nak->count () << " sns"
        //     << endl;

        Message_ptr m (new Message);

        m->add (Profile_ptr (nak.release ()));

        msgs.push_back (m);
      }
    }

    // Detect and record new losses.
    //
    for (u64 sn (q.sn () + 1), end (q.max_sn ()); sn < end; ++sn)
    {
      if (q.find (sn) == -1)
      {
        q.bind (sn, Descr (1));
      }
    }
  }
Exemplo n.º 15
0
  ssize_t Socket_Impl::
    recv_ (void* buf,
           size_t s,
           ACE_Time_Value const* timeout,
           ACE_INET_Addr* from)
    {
      ACE_Time_Value abs_time;

      if (timeout)
        abs_time = ACE_OS::gettimeofday () + *timeout;

      Lock l (mutex_);

      while (queue_.is_empty ())
        {
          if (timeout)
            {
              if (cond_.wait (&abs_time) != -1)
                break;
            }
          else
            {
              if (cond_.wait () != -1)
                break;
            }

          return -1; // errno is already set
        }


      Message_ptr m;

      if (queue_.dequeue_head (m) == -1)
        ACE_OS::abort ();


      if (queue_.is_empty ())
        {
          // Remove data from the pipe.
          //
          if (signal_pipe_.read_handle () != ACE_INVALID_HANDLE)
            {
              char c;

              if (signal_pipe_.recv (&c, 1) != 1)
                {
                  ACE_OS::perror ("read: ");
                  ACE_OS::abort ();
                }
            }
        }

      if (from)
        *from = static_cast<From const*> (m->find (From::id))->address ();

      if (m->find (NoData::id) != 0)
        {
          errno = ENOENT;
          return -1;
        }

      Data const* d = static_cast<Data const*>(m->find (Data::id));

      ssize_t r (static_cast<ssize_t> (d->size () < s ? d->size () : s));

      ACE_OS::memcpy (buf, d->buf (), r);

      return r;
    }
Exemplo n.º 16
0
  void Reassemble::recv (Message_ptr m)
  {
    Map::ENTRY* e = 0;
    Address from (
      static_cast<From const*> (m->find (From::id))->address ());

    if (Data const* data = static_cast<Data const*> (m->find (Data::id)))
    {
      if (Part const* part = static_cast<Part const*> (m->find (Part::id)))
      {
        if (map_.find (from, e) == -1)
        {
          // First part of the message.
          //

          if (part->num () != 1)
          {
            // We assume that we received NoData for one of the preceding
            // fragments. Ignore this one.
            return;
          }

          Data_ptr new_data (new Data (data->buf (),
                                       static_cast<size_t> (data->size ()),
                                       static_cast<size_t> (part->total_size ())));

          //std::cerr << "part->total_size (): " << part->total_size () << endl;

          map_.bind (from, new_data);
        }
        else
        {
          // Next part of the message.
          //

          if (part->num () == 1)
            ACE_OS::abort ();


          Data const* data = static_cast<Data const*> (m->find (Data::id));

          Data_ptr& new_data = e->int_id_;

          ACE_OS::memcpy (new_data->buf () + new_data->size (),
                          data->buf (),
                          data->size ());

          //std::cerr << "data->size (): " << data->size () << endl
          //          << "new_data->size (): " << new_data->size () << endl
          //          << "new_data->capa (): " << new_data->capacity () << endl;

          new_data->size (new_data->size () + data->size ());


          if (part->num () == part->of ())
          {
            // Reassembly is complete.
            //
            if (part->total_size () != new_data->size ())
              ACE_OS::abort ();

            Message_ptr new_msg (new Message ());

            Address to (
              static_cast<To const*> (m->find (To::id))->address ());

            new_msg->add (Profile_ptr (new To (to)));
            new_msg->add (Profile_ptr (new From (from)));
            /*
             * Heads up... we need to add the new_data to new_msg then
             * unbind the entry that maps to new_data, which will decrement
             * its reference count. If the bound/refcounted pointer acted
             * polymorphically like a regular pointer does, we'd be able to
             * just pass new_data to add(Profile_Ptr) and it would work.
             * However, Profile_Ptr and Data_Ptr are not compatible, but
             * we can use the secret knowledge that both are instances of the
             * same template and that the pointers they contain really are
             * hierarchically compatible, and do this funky cast to get
             * the result we want.
             */
            //new_msg->add (*(reinterpret_cast<Profile_ptr*> (&new_data)));

            new_msg->add (Profile_ptr (new_data));

            map_.unbind (from);

            in_->recv (new_msg);
          }
        }
      }
      else
      {
        // Non-fragmented message. Make sure we are in the consistent state
        // and forward it up.
        //
        if (map_.find (from, e) != -1)
          ACE_OS::abort ();

        in_->recv (m);
      }
    }
    else if (m->find (NoData::id) != 0)
    {
      if (map_.find (from, e) != -1)
      {
        // We already received some fragments. Clean everyhting up.
        //
        map_.unbind (from);
      }

      in_->recv (m);
    }
  }