Beispiel #1
0
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;
}
Beispiel #2
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #8
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;
}
Beispiel #9
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;
}