summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/Event/EC_ProxySupplier.h
blob: 590d5c611906554991e5e9e51bfda6881d16902d (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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/* -*- C++ -*- */
/**
 *  @file   EC_ProxySupplier.h
 *
 *  $Id$
 *
 *  @author Carlos O'Ryan (coryan@cs.wustl.edu)
 *
 * Based on previous work by Tim Harrison (harrison@cs.wustl.edu) and
 * other members of the DOC group. More details can be found in:
 *
 * http://doc.ece.uci.edu/~coryan/EC/index.html
 */

#ifndef TAO_EC_PROXYSUPPLIER_H
#define TAO_EC_PROXYSUPPLIER_H

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

#include "orbsvcs/orbsvcs/RtecEventChannelAdminS.h"

#include "EC_Filter.h"

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

class TAO_EC_Event_Channel_Base;
class TAO_EC_ProxyPushConsumer;

/**
 * @class TAO_EC_ProxyPushSupplier
 *
 * @brief ProxyPushSupplier
 *
 * Implement the RtecEventChannelAdmin::ProxyPushSupplier interface,
 * remember that this class is used to communicate with a
 * PushConsumer, so, in effect, this is the ambassador for a
 * consumer inside the event channel.
 *
 * <H2>Memory Management</H2>
 * It does not assume ownership of the TAO_EC_Dispatching object.
 * It makes a copy of the ConsumerQOS and the consumer object
 * reference.
 *
 * <H2>Locking</H2>
 * Locking is strategized, the event channel acts as a factory for
 * the locking strategies.
 *
 * @todo We don't need to provide a trivial filter, the object itself
 * could short-circuit the filter() ---> push() cycle when the EC
 * is properly configured, we need to explore this...
 */
class TAO_RTEvent_Export TAO_EC_ProxyPushSupplier : public TAO_EC_Filter
{
public:
  typedef RtecEventChannelAdmin::ProxyPushSupplier Interface;
  typedef RtecEventChannelAdmin::ProxyPushSupplier_var _var_type;
  typedef RtecEventChannelAdmin::ProxyPushSupplier_ptr _ptr_type;

  /// Constructor...
  TAO_EC_ProxyPushSupplier (TAO_EC_Event_Channel_Base* event_channel, int validate_connection);

  /// Destructor...
  virtual ~TAO_EC_ProxyPushSupplier (void);

  /// Activate in the POA
  virtual void activate (
       RtecEventChannelAdmin::ProxyPushSupplier_ptr &proxy
       ACE_ENV_ARG_DECL)
   ACE_THROW_SPEC ((CORBA::SystemException)) = 0;

  /// Deactivate from the POA
  virtual void deactivate (ACE_ENV_SINGLE_ARG_DECL)
    ACE_THROW_SPEC (());

  /// Disconnect this from
  virtual void disconnect_push_supplier (
            ACE_ENV_SINGLE_ARG_DECL) = 0;

  /// Return 0 if no consumer is connected...
  CORBA::Boolean is_connected (void) const;

  /// Return 1 if it is suspended.
  CORBA::Boolean is_suspended (void) const;

  /**
   * Return the consumer object reference. It returns nil() if it has
   * not connected yet.
   */
  RtecEventComm::PushConsumer_ptr consumer (void) const;

  /// The QoS (subscription) used to connect to the EC.
  const RtecEventChannelAdmin::ConsumerQOS& subscriptions (void) const;

  /// Concrete implementations can use this methods to keep track of
  /// the suppliers that publish its events.
  virtual void connected (TAO_EC_ProxyPushConsumer *consumer
                          ACE_ENV_ARG_DECL);
  virtual void reconnected (TAO_EC_ProxyPushConsumer *consumer
                            ACE_ENV_ARG_DECL);
  virtual void disconnected (TAO_EC_ProxyPushConsumer *consumer
                            ACE_ENV_ARG_DECL);

  /// Usually implemented as no-ops, but some configurations may
  /// require this methods.
  virtual void connected (TAO_EC_ProxyPushSupplier *supplier
                          ACE_ENV_ARG_DECL);
  virtual void reconnected (TAO_EC_ProxyPushSupplier *supplier
                            ACE_ENV_ARG_DECL);
  virtual void disconnected (TAO_EC_ProxyPushSupplier *supplier
                             ACE_ENV_ARG_DECL);

  /// The event channel is shutting down
  virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL);

  /// Pushes to the consumer, verifies that it is connected and that it
  /// is not suspended.
  /**
   * These methods take @a consumer argument  because during the time
   * the filters have been processing the event, this proxy's consumer
   * may have changed.
   */
  void push_to_consumer (RtecEventComm::PushConsumer_ptr consumer,
                         const RtecEventComm::EventSet &event
                         ACE_ENV_ARG_DECL);
  void reactive_push_to_consumer (RtecEventComm::PushConsumer_ptr consumer,
                                  const RtecEventComm::EventSet &event
                                  ACE_ENV_ARG_DECL);

  /**
   * Invoke the _non_existent() pseudo-operation on the consumer. If
   * it is disconnected then it returns true and sets the
   * <disconnected> flag.
   */
  CORBA::Boolean consumer_non_existent (CORBA::Boolean_out disconnected
                                        ACE_ENV_ARG_DECL);

  /// Increment and decrement the reference count.
  CORBA::ULong _incr_refcnt (void);
  CORBA::ULong _decr_refcnt (void);

  // = The TAO_EC_Filter methods, only push() is implemented...
  virtual int filter (const RtecEventComm::EventSet &event,
                      TAO_EC_QOS_Info& qos_info
                      ACE_ENV_ARG_DECL);
  virtual int filter_nocopy (RtecEventComm::EventSet &event,
                             TAO_EC_QOS_Info &qos_info
                             ACE_ENV_ARG_DECL);
  virtual void push (const RtecEventComm::EventSet &event,
                     TAO_EC_QOS_Info& qos_info
                     ACE_ENV_ARG_DECL);
  virtual void push_nocopy (RtecEventComm::EventSet &event,
                            TAO_EC_QOS_Info &qos_info
                            ACE_ENV_ARG_DECL);
  virtual void clear (void);
  virtual CORBA::ULong max_event_size (void) const;
  virtual int can_match (const RtecEventComm::EventHeader &header) const;
  virtual int add_dependencies (const RtecEventComm::EventHeader &header,
                                const TAO_EC_QOS_Info &qos_info
                                ACE_ENV_ARG_DECL);

protected:
  /// Set the consumer, used by some implementations to change the
  /// policies used when invoking operations on the consumer.
  void consumer (RtecEventComm::PushConsumer_ptr consumer);
  void consumer_i (RtecEventComm::PushConsumer_ptr consumer);

  void suspend_connection_i (ACE_ENV_SINGLE_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException));
  void resume_connection_i (ACE_ENV_SINGLE_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException));
  void suspend_connection_locked (ACE_ENV_SINGLE_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException));
  void resume_connection_locked (ACE_ENV_SINGLE_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException));

  /// The private version (without locking) of is_connected().
  CORBA::Boolean is_connected_i (void) const;

  /// Release the child and the consumer
  void cleanup_i (void);

  /// The Event Channel that owns this object.
  TAO_EC_Event_Channel_Base* event_channel_;

  /// The locking strategy.
  ACE_Lock* lock_;

  /// The reference count.
  CORBA::ULong refcount_;

  /// The consumer....
  RtecEventComm::PushConsumer_var consumer_;

  /// Is this consumer suspended?
  CORBA::Boolean suspended_;

  /// The subscription and QoS information...
  RtecEventChannelAdmin::ConsumerQOS qos_;

  /// Store the default POA.
  PortableServer::POA_var default_POA_;

  /// The filter object
  TAO_EC_Filter* child_;

  /// Validate the connection to consumer on connect
  int consumer_validate_connection_;
private:

  /// Template method hooks.
  virtual void refcount_zero_hook (void);
  virtual void pre_dispatch_hook (RtecEventComm::EventSet&
                                  ACE_ENV_ARG_DECL);
  virtual PortableServer::ObjectId
            object_id (ACE_ENV_SINGLE_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException)) = 0;
};

#if defined (__ACE_INLINE__)
#include "EC_ProxySupplier.i"
#endif /* __ACE_INLINE__ */

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

#endif /* TAO_EC_PROXYSUPPLIER_H */