summaryrefslogtreecommitdiff
path: root/ACE/examples/Monitor/Constraint/constraint.cpp
blob: d3e7d5a5ffa254da18e9b12233f5607c8b66cd0f (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
// $Id$

#include "ace/OS_NS_unistd.h"
#include "ace/Monitor_Control_Action.h"

#include "ace/Monitor_Control/Monitor_Control.h"

#include "examples/Monitor/MC_Test_Utilities.h"

#if defined (ACE_HAS_MONITOR_FRAMEWORK) && (ACE_HAS_MONITOR_FRAMEWORK == 1)

using namespace ACE_VERSIONED_NAMESPACE_NAME::ACE::Monitor_Control;

/// Two control actions that will be associated with two different
/// constraints on the same monitor.

class Trigger8k : public Control_Action
{
  virtual void execute (const char* /* command */)
  {
    ACE_DEBUG ((LM_DEBUG, "Total bytes received is above 8k\n"));
  }
};

class Trigger16k : public Control_Action
{
  virtual void execute (const char* /* command */)
  {
    ACE_DEBUG ((LM_DEBUG, "Total bytes received is above 16k\n"));
  }
};

/// Subclass of ACE_Task_Base, meaning that the override of
/// the svc() method below will run in a new thread when
/// activate() is called on a class instance.
class Monitor_Checker : public ACE_Task_Base
{
public:
  int svc (void)
  {
    /// Get an instance of the MC service singleton.
    MC_ADMINMANAGER* mgr =
      ACE_Dynamic_Service<MC_ADMINMANAGER>::instance ("MC_ADMINMANAGER");

    /// Call on the administrator class to look up the desired monitors.
    Monitor_Base *bytes_monitor =
      mgr->admin ().monitor_point ("OS/Network/BytesReceived");

    if (bytes_monitor != 0)
      {
        /// Query the monitor for its data every 2 seconds, and call the
        /// appropriate display function.
        for (int i = 0; i < 10; ++i)
          {
            ACE_OS::sleep (2);

            Monitor_Control_Types::Data data (bytes_monitor->type ());
            bytes_monitor->retrieve (data);
            MC_Test_Utilities::display_bytes_received (data);
          }

        bytes_monitor->remove_ref ();
      }

    return 0;
  }
};

#endif /* ACE_HAS_MONITOR_FRAMEWORK==1 */

int
ACE_TMAIN (int /* argc */, ACE_TCHAR * /* argv */ [])
{
#if defined (ACE_HAS_MONITOR_FRAMEWORK) && (ACE_HAS_MONITOR_FRAMEWORK == 1)

  /// Set the timer for # of threads check at 2 sec.
  Monitor_Base *bytes_monitor =
    create_os_monitor<BYTES_RECEIVED_MONITOR> (0, ACE_Time_Value (2));

  /// Add two constraints, each with its own triggered action.

  Trigger8k *trigger8k = new Trigger8k;
  long id8 = bytes_monitor->add_constraint ("value > 8192", trigger8k);

  ACE_DEBUG ((LM_DEBUG, "trigger8k id = %d\n", id8));

  Trigger16k *trigger16k = new Trigger16k;
  long id16 = bytes_monitor->add_constraint ("value > 16384", trigger16k);

  ACE_DEBUG ((LM_DEBUG, "trigger16k id = %d\n", id16));

  /// Create a query and register it to be called periodically.
  Monitor_Query query ("OS/Network/BytesReceived");
  Monitor_Point_Auto_Query *auto_query = new Monitor_Point_Auto_Query;
  auto_query->reference_counting_policy ().value (
    ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
  ACE_Event_Handler_var safety (auto_query);
  ADD_PERIODIC_QUERY (auto_query, &query, ACE_Time_Value (2));

  /// Runs the reactor's event loop in a separate thread so the timer(s)
  /// can run concurrently with the application.
  START_PERIODIC_MONITORS;

  /// Run the monitor checker in a separate thread. This class will
  /// fetch the monitor's value directly, and its output will be
  /// separate from the output from triggered actions.
  Monitor_Checker monitor_checker;
  monitor_checker.activate ();

  ACE_OS::sleep (20);

  /// Can do a remove_ref() on this returned value or on the original
  /// control action 'trigger8k', but not on both, since they point to
  /// the same thing.
  Control_Action *removed_action = bytes_monitor->remove_constraint (id8);
  ACE_DEBUG ((LM_DEBUG, "8k trigger removed\n"));

  ACE_OS::sleep (5);

  /// End the reactor's event loop, stopping the timer(s).
  STOP_PERIODIC_MONITORS;

  /// Do this instead of 'delete' since they are refcounted.
  removed_action->remove_ref ();
  trigger16k->remove_ref ();
  bytes_monitor->remove_ref ();

#endif /* ACE_HAS_MONITOR_FRAMEWORK==1 */

  return 0;
}