summaryrefslogtreecommitdiff
path: root/TAO/tao/LF_Event.h
blob: 0a721b4cad42f349ca29099cc9b86edb179d4ae1 (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
// -*- C++ -*-

//=============================================================================
/**
 *  @file LF_Event.h
 *
 *  $Id$
 *
 *  @author Carlos O'Ryan <coryan@uci.edu>
 */
//=============================================================================

#ifndef TAO_LF_EVENT_H
#define TAO_LF_EVENT_H

#include /**/ "ace/pre.h"

#include "TAO_Export.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

class TAO_LF_Follower;
class TAO_Leader_Follower;

/**
 * @class TAO_LF_Event
 *
 * @brief Use the Leader/Follower loop to wait for one specific event.
 *
 * The Leader/Follower event loop is used to wait for incoming
 * responses, as well as to wait for all the data to be flushed.
 * This class encapsulates this event loop. It uses Template Method to
 * parametrize the 'waited for' predicate (i.e. reply received or
 * message sent or connection establishment etc.)
 *
 * @todo Implementing the Leader/Followers loop in this class, as
 * well as the callbacks to communicate that an event has completed
 * leads to excessive coupling.  A better design would use a separate
 * class to signal the events, that would allow us to remove the
 * Leader/Followers logic from the ORB.  However, that requires other
 * major changes and it somewhat complicates the design.
 *
 */
class TAO_Export TAO_LF_Event
{
public:

  friend class TAO_Leader_Follower;

  /// Constructor
  TAO_LF_Event (void);

  /// Destructor
  virtual ~TAO_LF_Event (void);

  /// Bind a follower
  /**
   * An event can be waited on by at most one follower thread, this
   * method is used to bind the waiting thread to the event, in order
   * to let the event signal any important state changes.
   *
   * @return -1 if the LF_Event is already bound, 0 otherwise
   */
  int bind (TAO_LF_Follower *follower);

  /// Unbind the follower
  int unbind (void);

  //@{
  /** @name State management
   *
   * A Leader/Followers event goes through several states during its
   * lifetime. We use an enum to represent those states and state
   * changes are validated according to the rules defined in the
   * concrete classes. We treat the states as finite states in a
   * FSM. The possible sequence of states through which the FSM
   * migrates is defined in the concrete classes.
   */
  enum {
    /// The event is created, and is in initial state
    LFS_IDLE = 0,
    /// The event is active
    LFS_ACTIVE,
    /// The event is waiting for connection completion.
    LFS_CONNECTION_WAIT,
    /// The event has completed successfully
    LFS_SUCCESS,
    /// A failure has been detected while the event was active
    LFS_FAILURE,
    /// The event has timed out
    LFS_TIMEOUT,
    /// The connection was closed.
    LFS_CONNECTION_CLOSED
  };

  /**
   * Virtual methods for this class hierarchy..
   */
  /// Accessor to change the state. The state isnt changed unless
  /// certain conditions are satisfied.
  void state_changed (int new_state,
                      TAO_Leader_Follower &lf);

  /// Return 1 if the condition was satisfied successfully, 0 if it
  /// has not
  virtual int successful (void) const = 0 ;

  /// Return 1 if an error was detected while waiting for the
  /// event
  virtual int error_detected (void) const = 0;

  /// Check if we should keep waiting.
  int keep_waiting (void);
  //@}

  /// Reset the state, irrespective of the previous states
  void reset_state (int new_state);

protected:

  /// Validate the state change
  virtual void state_changed_i (int new_state) = 0;

  /// Check whether we have reached the final state..
  virtual int is_state_final (void) = 0;

private:

  /// Set the state irrespective of anything.
  virtual void set_state (int new_state);

protected:
  /// The current state
  int state_;

  /// The bounded follower
  TAO_LF_Follower *follower_;
};

#if defined (__ACE_INLINE__)
# include "LF_Event.inl"
#endif /* __ACE_INLINE__ */

#include /**/ "ace/post.h"

#endif  /* TAO_LF_EVENT_H */