summaryrefslogtreecommitdiff
path: root/docs/tutorials/011/task.cpp
blob: d777d0e32d89ff85b502ce65d17b47c5df0dd231 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// $Id$

#include "task.h"
#include "block.h"
#include "data.h"
#include "ace/OS_NS_unistd.h"

Task::Task (size_t n_threads)
  : barrier_ (n_threads),
    n_threads_ (n_threads)
{
  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) Task ctor 0x%x\n",
              (void *) this));
}

Task::~Task (void)
{
  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) Task dtor 0x%x\n",
              (void *) this));

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

int
Task::open (void *)
{
    return this->activate (THR_NEW_LWP,
                        this->n_threads_);

}

int
Task::close (u_long flags)
{
  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) Task close 0x%x\n",
              (void *) this));
  return inherited::close (flags);
}

int
Task::svc (void)
{
  this->barrier_.wait ();

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) Task 0x%x starts in thread %d\n",
              (void *) this,
              ACE_Thread::self ()));

  ACE_Message_Block *message;

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

      if (message->msg_type () == ACE_Message_Block::MB_HANGUP)
        {
          this->putq (message);

          break;
        }

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

      ACE_DEBUG ((LM_DEBUG,
                  "(%P|%t) Block 0x%x contains (%s)\n",
                  (void *) message,
                  cp));

      /* Create a Data object into which we can extract the message
        block contents.  */
      Data data;

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

      /* Invoke a couple of method calls on the object we constructed.  */
      data.who_am_i ();
      data.what_am_i ();

      /* 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...  */


      ACE_OS::sleep (ACE_Time_Value (0, 5000));

      message->release ();
    }

  return 0;
}