static void * producer (ACE_Message_Queue<ACE_MT_SYNCH> *msg_queue) { ACE_Read_Buffer rb (ACE_STDIN); // Keep reading stdin, until we reach EOF. for (;;) { // Allocate a new buffer. char *buffer = rb.read ('\n'); ACE_Message_Block *mb = 0; if (buffer == 0) { // Send a 0-sized shutdown message to the other thread and // exit. ACE_NEW_RETURN (mb, ACE_Message_Block ((size_t) 0), 0); if (msg_queue->enqueue_tail (mb) == -1) ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put_next")); break; } // Enqueue the message in priority order. else { // Allocate a new message, but have it "borrow" its memory // from the buffer. ACE_NEW_RETURN (mb, ACE_Message_Block (rb.size (), ACE_Message_Block::MB_DATA, 0, buffer), 0); mb->msg_priority (ACE_Utils::truncate_cast<unsigned long> (rb.size ())); mb->wr_ptr (rb.size ()); ACE_DEBUG ((LM_DEBUG, "enqueueing message of size %d\n", mb->msg_priority ())); // Enqueue in priority order. if (msg_queue->enqueue_prio (mb) == -1) ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put_next")); } } // Now read all the items out in priority order (i.e., ordered by // the size of the lines!). consumer (msg_queue); return 0; }
static void * consumer (void *args) { ACE_Message_Queue<ACE_MT_SYNCH> *msg_queue = reinterpret_cast<ACE_Message_Queue<ACE_MT_SYNCH> *> (args); u_long cur_priority = 27; ACE_UNUSED_ARG (cur_priority); // To suppress ghs warning about unused local variable // "cur_priority". int local_count = 0; // Keep looping, reading a message out of the queue, until we get a // message with a length == 0, which signals us to quit. for (char c = 'z'; ; c--) { ACE_Message_Block *mb = 0; int result = msg_queue->dequeue_head (mb); if (result == -1) break; local_count++; size_t length = mb->length (); if (length > 0) { // This isn't a "shutdown" message, so process it // "normally." ACE_TEST_ASSERT (c == *mb->rd_ptr ()); ACE_TEST_ASSERT (mb->msg_priority () < cur_priority); cur_priority = mb->msg_priority (); } // Free up the buffer memory and the Message_Block. Note that // the destructor of Message Block will delete the the actual // buffer. mb->release (); if (length == 0) // This was a "shutdown" message, so break out of the loop. break; } ACE_TEST_ASSERT (local_count == message_count); return 0; }
int Message_Handler::svc (void) { for (int i = 0;; i++) { ACE_Message_Block *mb; ACE_NEW_RETURN (mb, ACE_Message_Block (1), 0); mb->msg_priority (i); ACE_OS::sleep (1); // Note that this putq() call with automagically invoke the // notify() hook of our ACE_Reactor_Notification_Strategy, // thereby informing the <ACE_Reactor> Singleton to call our // <handle_input> method. if (this->putq (mb) == -1) { if (errno == ESHUTDOWN) ACE_ERROR_RETURN ((LM_ERROR, "(%t) queue is deactivated"), 0); else ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "putq"), -1); } } ACE_NOTREACHED (return 0); }
ACE_Dynamic_Message_Strategy::Priority_Status ACE_Dynamic_Message_Strategy::priority_status (ACE_Message_Block & mb, const ACE_Time_Value & tv) { // default the message to have pending priority status Priority_Status status = ACE_Dynamic_Message_Strategy::PENDING; // start with the passed absolute time as the message's priority, then // call the polymorphic hook method to (at least partially) convert // the absolute time and message attributes into the message's priority ACE_Time_Value priority (tv); convert_priority (priority, mb); // if the priority is negative, the message is pending if (priority < ACE_Time_Value::zero) { // priority for pending messages must be shifted // upward above the late priority range priority += pending_shift_; if (priority < min_pending_) priority = min_pending_; } // otherwise, if the priority is greater than the maximum late // priority value that can be represented, it is beyond late else if (priority > max_late_) { // all messages that are beyond late are assigned lowest priority (zero) mb.msg_priority (0); return ACE_Dynamic_Message_Strategy::BEYOND_LATE; } // otherwise, the message is late, but its priority is correct else status = ACE_Dynamic_Message_Strategy::LATE; // use (fast) bitwise operators to isolate and replace // the dynamic portion of the message's priority mb.msg_priority((mb.msg_priority() & static_bit_field_mask_) | ((priority.usec () + ACE_ONE_SECOND_IN_USECS * (suseconds_t)(priority.sec())) << static_bit_field_shift_)); // returns the priority status of the message return status; }
bool TAO_Notify_Buffering_Strategy::discard (TAO_Notify_Method_Request_Queueable* method_request) { if (this->shutdown_) { return false; } ACE_Message_Block* mb = 0; int result = -1; if (this->discard_policy_.is_valid() == 0 || this->discard_policy_ == CosNotification::AnyOrder || this->discard_policy_ == CosNotification::FifoOrder) { result = this->msg_queue_.dequeue_head (mb); } else if (this->discard_policy_ == CosNotification::LifoOrder) { // The most current message is NOT the newest one in the queue. It's // the one we're about to add to the queue. result = -1; } else if (this->discard_policy_ == CosNotification::DeadlineOrder) { result = this->msg_queue_.dequeue_deadline (mb); } else if (this->discard_policy_ == CosNotification::PriorityOrder) { result = this->msg_queue_.dequeue_prio (mb); if (mb->msg_priority() >= method_request->msg_priority()) { this->msg_queue_.enqueue_prio (mb); result = -1; } } else { if (TAO_debug_level > 0) ORBSVCS_DEBUG ((LM_DEBUG, "Notify (%P|%t) - Invalid discard policy\n")); result = this->msg_queue_.dequeue_head (mb); } if (result != -1) { ACE_Message_Block::release (mb); return true; } return false; }
static void * producer (void *args) { ACE_Message_Queue<ACE_MT_SYNCH> *msg_queue = reinterpret_cast<ACE_Message_Queue<ACE_MT_SYNCH> *> (args); ACE_Message_Block *mb = 0; for (const char *c = ACE_ALPHABET; *c != '\0'; c++) { ++message_count; // Allocate a new message ACE_NEW_RETURN (mb, ACE_Message_Block (1), 0); *mb->wr_ptr () = *c; // Set the priority. mb->msg_priority (message_count); mb->wr_ptr (1); // Enqueue in priority order. if (msg_queue->enqueue_prio (mb) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%t) %p\n"), ACE_TEXT ("put_next")), 0); } // Now send a 0-sized shutdown message to the other thread ACE_NEW_RETURN (mb, ACE_Message_Block ((size_t) 0), 0); if (msg_queue->enqueue_tail (mb) == -1) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%t) %p\n"), ACE_TEXT ("put_next"))); ++message_count; // Now read all the items out in priority order (i.e., ordered by // the size of the lines!). consumer (msg_queue); return 0; }
int Message_Handler::handle_input (ACE_HANDLE) { ACE_DEBUG ((LM_DEBUG, "(%t) Message_Handler::handle_input\n")); ACE_Message_Block *mb; if (this->getq (mb, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) ACE_ERROR ((LM_ERROR, "(%t) %p\n", "dequeue_head")); else { ACE_DEBUG ((LM_DEBUG, "(%t) priority = %d\n", mb->msg_priority ())); mb->release (); } return 0; }
static void * producer (ACE_Message_Queue<ACE_MT_SYNCH> *msg_queue) { // Keep reading stdin, until we reach EOF. for (int n; ; ) { // Allocate a new message. ACE_Message_Block *mb = 0; ACE_NEW_RETURN (mb, ACE_Message_Block (BUFSIZ), 0); n = ACE_OS::read (ACE_STDIN, mb->wr_ptr (), mb->size ()); if (n <= 0) { // Send a shutdown message to the other thread and exit. mb->length (0); if (msg_queue->enqueue_tail (mb) == -1) ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put_next")); break; } // Send the message to the other thread. else { mb->msg_priority (n); mb->wr_ptr (n); if (msg_queue->enqueue_tail (mb) == -1) ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put_next")); } } return 0; }
int Worker_Task::svc (void) { // The <ACE_Task::svc_run()> method automatically adds us to the // process-wide <ACE_Thread_Manager> when the thread begins. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) starting svc() method\n"))); // Keep looping, reading a message out of the queue, until we get a // message with a length == 0, which signals us to quit. for (int count = 0; ; count++) { ACE_Message_Block *mb = 0; if (-1 == this->msg_queue ()->dequeue_head (mb)) ACE_ERROR_BREAK ((LM_ERROR, ACE_TEXT ("(%t) %p\n"), ACE_TEXT ("Worker_Task dequeue_head"))); size_t length = mb->length (); // If there's a next() Task then "logically" copy the message by // calling <duplicate> and send it on down the pipeline. Note // that this doesn't actually make a copy of the message // contents (i.e., the Data_Block portion), it just makes a copy // of the header and reference counts the data. if (this->next () != 0) { if (-1 == this->put_next (mb->duplicate ())) ACE_ERROR_BREAK ((LM_ERROR, ACE_TEXT ("(%t) %p\n"), ACE_TEXT ("Worker_Task put_next"))); } // If there's no next() Task to send to, then we'll consume the // message here. else if (length > 0) { int current_count = ACE_OS::atoi ((ACE_TCHAR *)(mb->rd_ptr ())); int i; if (count != current_count) ACE_ERROR_BREAK ((LM_ERROR, ACE_TEXT ("(%t) count from block should be %d ") ACE_TEXT ("but is %d\n"), count, current_count)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) enqueueing %d duplicates\n"), current_count)); ACE_Message_Block *dup; // Enqueue <current_count> duplicates with msg_priority == 1. for (i = current_count; i > 0; i--) { ACE_ALLOCATOR_RETURN (dup, mb->duplicate (), -1); // Set the priority to be greater than "normal" // messages. Therefore, all of these messages should go // to the "front" of the queue, i.e., ahead of all the // other messages that are being enqueued by other // threads. dup->msg_priority (ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY + 1); int enqueue_prio_result = this->msg_queue ()->enqueue_prio (dup, // Don't block indefinitely if we flow control... (ACE_Time_Value *) &ACE_Time_Value::zero); if (enqueue_prio_result == -1) ACE_ERROR_BREAK ((LM_ERROR, ACE_TEXT ("(%t) Pass %d %p\n"), i, ACE_TEXT ("Worker_Task enqueue_prio"))); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) dequeueing %d duplicates\n"), current_count)); // Dequeue the same <current_count> duplicates. for (i = current_count; i > 0; i--) { if (-1 == this->msg_queue ()->dequeue_head (dup)) ACE_ERROR_BREAK ((LM_ERROR, ACE_TEXT ("(%t) Dup %d, %p\n"), i, ACE_TEXT ("Worker_Task dequeue dups"))); if (count != ACE_OS::atoi ((ACE_TCHAR *)(dup->rd_ptr ()))) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%t) line %l, Dup %d, block's count ") ACE_TEXT ("is %d but should be %d\n"), i, ACE_OS::atoi ((ACE_TCHAR *)(dup->rd_ptr ())), count)); if (0 != ACE_OS::strcmp ((ACE_TCHAR *)mb->rd_ptr (), (ACE_TCHAR *)dup->rd_ptr ())) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%t) Dup %d text is %s; ") ACE_TEXT ("should be %s\n"), i, dup->rd_ptr (), mb->rd_ptr ())); if (dup->msg_priority () != ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY + 1) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%t) Dup %d block priority is %u; ") ACE_TEXT ("should be %u\n"), i, (unsigned int)dup->msg_priority (), (unsigned int)(ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY + 1))); dup->release (); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) in iteration %d, length = %B, prio = %d, text = \"%*s\"\n"), count, length, mb->msg_priority (), (int)(length - 2), // remove the trailing "\n\0" mb->rd_ptr ())); } // We're responsible for deallocating this. mb->release (); if (length == 0) { //FUZZ: disable check_for_NULL ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) in iteration %d, queue len = %B, got NULL message, exiting\n"), count, this->msg_queue ()->message_count ())); //FUZZ: enable check_for_NULL break; } } // Note that the ACE_Task::svc_run () method automatically removes // us from the Thread_Manager when the thread exits. return 0; }