Sophie

Sophie

distrib > Mandriva > 10.0 > i586 > media > contrib > by-pkgid > 21280410b6ea906d791d7a12afae2579 > files > 167

libace5-doc-5.4-2mdk.i586.rpm

<!-- page03.html,v 1.11 2000/03/19 20:09:26 jcej Exp -->
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <META NAME="Author" CONTENT="James CE Johnson">
   <TITLE>ACE Tutorial 011</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">

<CENTER><B><FONT SIZE=+2>ACE Tutorial 011</FONT></B></CENTER>

<CENTER><B><FONT SIZE=+2>Passing non-trivial data through an ACE_Message_Queue</FONT></B></CENTER>


<P>
<HR WIDTH="100%">

Our Task object <A HREF="task.h">declaration</a> and <A HREF="task.cpp">definition</a>.
  As with message_queue.cpp,
I've only commented the changes.
<P>

<HR WIDTH="100%">
<HR width=50%><P><center>task.h</center><HR width=50%>
<PRE>
<font color=red>// page03.html,v 1.11 2000/03/19 20:09:26 jcej Exp</font>

<font color=blue>#ifndef</font> <font color=purple>TASK_H</font>
<font color=blue>#define</font> <font color=purple>TASK_H</font>

<font color=blue>#include</font> "<A HREF="../../../ace/Task.h">ace/Task.h</A>"

<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>)
<font color=blue># pragma</font> <font color=purple>once</font>
<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font>

class Task : public ACE_Task &lt;ACE_MT_SYNCH>
{
public:

  typedef ACE_Task &lt;ACE_MT_SYNCH> inherited;

  Task (size_t n_threads);
  ~Task (void);

  int open (void * = 0);

  int svc (void);

  int close (u_long flags = 0);

protected:
  ACE_Barrier barrier_;

  size_t n_threads_;
};

<font color=blue>#endif</font> <font color=red>/* TASK_H */</font>
</PRE>
<HR width=50%><P><center>task.cpp</center><HR width=50%>
<PRE>
<font color=red>// page03.html,v 1.11 2000/03/19 20:09:26 jcej Exp</font>

<font color=blue>#include</font> "<font color=green>task.h</font>"
<font color=blue>#include</font> "<font color=green>block.h</font>"
<font color=blue>#include</font> "<font color=green>data.h</font>"

<font color=#008888>Task::Task</font> (size_t n_threads)
  : barrier_ (n_threads),
    n_threads_ (n_threads)
{
  ACE_DEBUG ((LM_DEBUG,
              "<font color=green>(%P|%t) Task ctor 0x%x\n</font>",
              (void *) this));
}

<font color=#008888>Task::~Task</font> (void)
{
  ACE_DEBUG ((LM_DEBUG,
              "<font color=green>(%P|%t) Task dtor 0x%x\n</font>",
              (void *) this));

  ACE_Message_Block *message;
  this->getq (message);
  message->release ();
}

int
<font color=#008888>Task::open</font> (void *)
{
    return this->activate (THR_NEW_LWP,
                        this->n_threads_);

}

int
<font color=#008888>Task::close</font> (u_long flags)
{
  ACE_DEBUG ((LM_DEBUG,
              "<font color=green>(%P|%t) Task close 0x%x\n</font>",
              (void *) this));
  return <font color=#008888>inherited::close</font> (flags);
}

int
<font color=#008888>Task::svc</font> (void)
{
  this->barrier_.wait ();

  ACE_DEBUG ((LM_DEBUG,
              "<font color=green>(%P|%t) Task 0x%x starts in thread %d\n</font>",
              (void *) this,
              <font color=#008888>ACE_Thread::self</font> ()));

  ACE_Message_Block *message;

  for (;;)
    {
      if (this->getq (message) == -1)
        ACE_ERROR_RETURN ((LM_ERROR,
                           "<font color=green>%p\n</font>",
                           "<font color=green>getq</font>"),
                          -1);

      if (message->msg_type () == <font color=#008888>ACE_Message_Block::MB_HANGUP</font>)
        {
          this->putq (message);

          break;
        }

      const char *cp = message->rd_ptr ();
      <font color=red>// Don't forget to skip the NULL we inserted</font>
      message->rd_ptr (<font color=#008888>ACE_OS::strlen</font> (cp) + 1);

      ACE_DEBUG ((LM_DEBUG,
                  "<font color=green>(%P|%t) Block 0x%x contains (%s)\n</font>",
                  (void *) message,
                  cp));

      <font color=red>/* Create a Data object into which we can extract the message
        block contents.  */</font>
      Data data;

      <font color=red>/* Use the rd_ptr() to access the message block data.  Note that
        we've already moved it past the text string in the block.  */</font>
      <font color=#008888>ACE_OS::memmove</font> ((char *) &data,
                       message->rd_ptr (),
                       sizeof (data));
      message->rd_ptr (sizeof (data));  <font color=red>// Move the rd_ptr() beyond the data.</font>

      <font color=red>/* Invoke a couple of method calls on the object we constructed.  */</font>
      data.who_am_i ();
      data.what_am_i ();

      <font color=red>/* An alternate approach:

        Data * data;
        data = (Data *)message->rd_ptr();
        data->who_am_i();
        data->what_am_i();
        message->rd_ptr(sizeof(Data));

        Even though this cuts down on the number of copies &
        constructions, I'm not real fond of it.  You can get into
        trouble in a hurry by treating memory blocks as multiple data
        types...  */</font>


      <font color=#008888>ACE_OS::sleep</font> (ACE_Time_Value (0, 5000));

      message->release ();
    }

  return 0;
}
</PRE>
<HR WIDTH="100%">
<P>
Notice how we had to create a temporary Data object to copy the stuff out
of the message block?  Again, if there were non-trivial ctor/dtors involved
then this wouldn't work at all.
<P>
Again, like <A HREF="../010/page01.html">Tutorial 10</A> we've skipped
<i>THR_DETACHED</i> because we <i>wait()</i> for the threads to exit
      elsewhere.
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER>