ACE Tutorial 012
Passing classes through ACE_Message_Queue

Ok, finally we get to main(). Sorry for the diversion but it was important to lay some of that groundwork before getting here.

    // page04.html,v 1.10 2000/03/19 20:09:26 jcej Exp

    #include "block.h"
    #include "work.h"
    #include "task.h"

    /*
      I want to be sure that our Task object gets destructed correctly, so
      I'll do most of the application 'work' in run_test() instead of
      main()
    */
    int run_test (int iterations, int threads)
    {
         /*
           Create the Task which is our thread pool for doing work
         */
      Task task;

      if (task.start (threads) == -1)
      {
        ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "start"), -1);
      }

       /*
         Give the Task a chance to enter it's svc() method.  This isn't
         really necessary and you probably wouldn't do it in a real
         application but it makes the output more interesting.
       */
      ACE_OS::sleep (ACE_Time_Value (1));

      for (int i = 0; i < iterations; ++i)
      {
        /*
           Construct a Work object that we'll put into the Queue.  Give it
           the iteration number so that it can identify itself in the output.
         */
        Work * data = new Work(i);

        /*
           Create a block that contains our Work object but also has
           enough room for a text message.
         */
        Message_Block *message = new Message_Block (128, data);

        /*
           As before, put a text message into the block.
         */
        ACE_OS::sprintf (message->wr_ptr (), "This is message %d.", i);
        message->wr_ptr (strlen (message->rd_ptr ())+1);

         /*
           Add the work to our thread pool
         */
        if (task.putq (message) == -1)
        {
          break;
        }
      }

       /*
         Insert a HANGUP message block to tell the thread pool to shut
         itself down.
        */
      Message_Block *message = new Message_Block (0,0);
      message->msg_type (ACE_Message_Block::MB_HANGUP);
      task.putq (message);

       /*
         Wait for the all threads of the Task to exit.  It is rather rude
         to let the Task go out of scope without doing this first.
       */
      task.wait ();

      return (0);
    }

    int main (int argc, char *argv[])
    {
         /*
           Give the user a chance to override the default number of
           iterations and pool threads.
         */
      int iterations = argc > 1 ? atoi (argv[1]) : 4;
      int threads = argc > 2 ? atoi (argv[2]) : 2;

       /*
         Use the function above to do the actual test.  As I said, this
         lets us see the Task go out of scope and destruct before our
         "exiting" message below.
       */
      (void) run_test (iterations, threads);

      ACE_DEBUG ((LM_DEBUG, "(%P|%t) Application exiting\n"));

      return (0);
    }

That certainly looks cleaner than the previous approach! If you blink, you'll miss the part where the Work object goes into the Queue.

[Tutorial Index] [Continue This Tutorial]