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; } } }
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); }
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); }
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); }
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; } } }
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)); } } }