summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/examples/FaultTolerance/FLARe/Timer.cpp
blob: acc801242eb6e10f2cc77eb9124deed5e12fc6c4 (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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

#include "Timer.h"
#include "ace/Timer_Queue.h"
#include "ace/Reactor.h"

//=================================================================

// constructor
Timer::Timer (void)
  : done_ (0),
    active_ (0),
    hertz_ (0),
    tid_ (0)
{
  // Setup a reactor different from what the ORB is using that we shall use
  // exclusively for timer capabilities.
  this->reactor (new ACE_Reactor);
}

// destructor
Timer::~Timer ()
{
  delete this->reactor ();
  this->reactor (0);
}

// get our attribute
double
Timer::hertz ()
{
  return this->hertz_;
}

// set our attribute
void
Timer::hertz (double h)
{
  this->hertz_ = h;
}

// start the timer
void
Timer::start ()
{
  // we are using this step in case we want to restart the timer capabilities
  // again
  this->done_ = 0;

  // check if parameters are valid
  if (this->hertz_ == 0 || this->active_ !=0) {        // Not valid
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT ("[Timer::start] ")
                ACE_TEXT ("Bad Parameters\n")));
    // we should throw some exception
    return;
  }

  // start an active object that will handle events - particularly timeout
  // events
  if (this->activate () == -1) {
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT ("[Timer::start] ")
                ACE_TEXT ("Active object activation failed (%p)\n")));
    // we should throw some exception
    return;
  }

  // we are now active
  this->active_ = 1;

  long int interval = 1000000 / hertz_;

  // start a periodic timer
  this->tid_ = this->reactor ()->schedule_timer (this,
                                                 0,
                                                 ACE_Time_Value (0, interval),
                                                 ACE_Time_Value (0, interval));

  if (this->tid_ == -1) {
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT ("[Timer::start] ")
                ACE_TEXT ("Scheduling timer failed (%p)\n")));
    // we should throw some exception
    return;
  }

  // success
}

// stopping the timer
void
Timer::stop ()
{
  if (this->active_ == 0) {      // Not valid.
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT ("[Timer::stop] ")
                ACE_TEXT ("bad parameter\n")));
    // we should throw some exception
    return;
  }

  // cancel the timer
  this->reactor ()->cancel_timer (this);

  // we are no longer active
  this->active_ = 0;

  // asynchronous notification to the active object thread
  this->done_ = 1;

  // send an event to the reactor which will invoke the handle_close
  this->reactor ()->notify ();

  ///ACE_DEBUG ((LM_DEBUG, "Waiting\n"));

  // wait for the active object thread to quit
  this->wait ();
}

// callback function from the timeout handler.
int
Timer::pulse (void)
{
  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("obtain utilization input\n")));

  return 0;
}

// handling the timeout
int
Timer::handle_timeout (const ACE_Time_Value &,
                                        const void *)
{
  // ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("[Timer::handle_timeout] - timeout\n")));
  // timeout has occured. Time to callback. The callback function will do the
  // RM's job of getting utilization info from the hosts.
  return this->pulse ();
}

// cleanup
int
Timer::handle_close (ACE_HANDLE handle,
                                      ACE_Reactor_Mask close_mask)
{
  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("[%x] handle = %d, close_mask = %d\n"),
              this,
              handle,
              close_mask));

  return 0;
}

// active object thread
int
Timer::svc (void)
{
  // set the owner
  this->reactor ()->owner (ACE_OS::thr_self ());

  // continue until someone stops us asynchronously
  while (!this->done_)
    this->reactor ()->handle_events ();

  return 0;
}