int ACE::HTBP::Session::flush_outbound_queue (void) { int result = 0; if (this->outbound_queue_.message_count() > 0) { ACE_Message_Block *msg = 0; iovec *iov = 0; ACE_NEW_RETURN (iov, iovec[this->outbound_queue_.message_count()], -1); ACE_Auto_Array_Ptr<iovec> guard (iov); this->outbound_queue_.peek_dequeue_head (msg); for (size_t i = 0; i < this->outbound_queue_.message_count(); i++) { iov[i].iov_base = msg->rd_ptr(); iov[i].iov_len = msg->length(); msg = msg->next(); } if (this->outbound_->state() == ACE::HTBP::Channel::Wait_For_Ack) this->outbound_->recv_ack(); result = this->outbound_->sendv (iov,this->outbound_queue_.message_count(),0); while (this->outbound_queue_.message_count ()) { this->outbound_queue_.dequeue_head (msg); msg->release (); } } return result; }
int Counting_Test_Producer::svc (void) { // Going to produce a lot of blocks. Since we don't necessarily want them // all consumed, there's no arrangement with the consumer to be sure that // the same number produced will be consumed; the test check will compare // the number produced, consumed, and remaining to be sure it ends up // correct. // Also, to be sure there's not just 1 producer and 1 consumer pinging // back and forth, make the producers randomly delay between blocks. ACE_OS::srand (static_cast<unsigned int> (ACE_OS::time ())); int multiple = ACE_OS::rand () % 10; int delay_ms = (ACE_OS::rand () % 10) / 2; // The delay usually causes the test to time out in the automated // regression testing. I just left it here in case it's needed someday. delay_ms = 0; long count = MESSAGE_FACTOR * (multiple ? multiple : 1); long produced = 0; // Some of the threads enqueue single blocks, others sequences. long lsequence = ++(this->sequence_); int seq = static_cast<int> (lsequence); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Producer will enqueue %B blocks in seq of %d, ") ACE_TEXT ("%d msec delay\n"), (size_t)count, seq, delay_ms)); ACE_Message_Block *first = 0, *prev = 0, *b = 0; ACE_Time_Value delay (0, delay_ms); ACE_Time_Value timeout (10); while (produced < count) { ACE_NEW_NORETURN (b, ACE_Message_Block (1)); if (b == 0) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Producer out of memory\n"))); break; } first = b; prev = first; for (int s = 1; s < seq; ++s) { ACE_NEW_NORETURN (b, ACE_Message_Block (1)); if (b == 0) break; prev->next (b); b->prev (prev); prev = b; } if (b == 0) { if (first != b) { while (first->next () != 0) { b = first->next (); first->release (); first = b; } first->release (); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Producer out of memory\n"))); break; } // To be sure we can keep going on slow or completed consumers, but not // delay excessively if the consumers have stopped, limit the time // spent waiting to 10 seconds. ACE_Time_Value block = ACE_OS::gettimeofday (); block += timeout; if (this->putq (first, &block) == -1) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Producer cannot putq; giving up\n"))); while (first->next () != 0) { b = first->next (); first->release (); first = b; } first->release (); break; } produced += seq; if (delay_ms) ACE_OS::sleep (delay); } this->produced_ += produced; ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Producer done\n"))); return 0; }