summaryrefslogtreecommitdiff
path: root/TAO/tao/Asynch_Reply_Dispatcher_Base.h
blob: b95b97d307a923f4e1205321e8abe848cdbe867c (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
// This may look like C, but it's really -*- C++ -*-
//=============================================================================
/**
 *  @file Asynch_Reply_Dispatcher_Base.h
 *
 *  $Id$
 *
 *  @author Alexander Babu Arulanthu <alex@cs.wustl.edu>
 *  @author Jeff Parsons <parsons@cs.wustl.edu>
 */
//=============================================================================

#ifndef TAO_ASYNCH_REPLY_DISPATCHER_BASE_H
#define TAO_ASYNCH_REPLY_DISPATCHER_BASE_H

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

#include "tao/Reply_Dispatcher.h"
#include "tao/CDR.h"

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

#include "tao/IOP_IORC.h"

class TAO_Pluggable_Reply_Params;
class TAO_ORB_Core ;
class ACE_Time_Value;
class TAO_Transport;
class ACE_Lock;

/**
 * @class TAO_Asynch_Reply_Dispatcher_Base
 *
 * @brief Base class for TAO_Asynch_Reply_Dispatcher and
 *  TAO_DII_Deferred_Reply_Dispatcher
 */

class TAO_Export TAO_Asynch_Reply_Dispatcher_Base
  : public TAO_Reply_Dispatcher
{
public:
  /// Default constructor.
  TAO_Asynch_Reply_Dispatcher_Base (TAO_ORB_Core *orb_core);

  /// Sets the transport for this invocation.
  void transport (TAO_Transport *t);

  // = The Reply Dispatcher methods
  virtual int dispatch_reply (TAO_Pluggable_Reply_Params &) = 0;

  virtual void connection_closed (void) = 0;

  /// Inform that the reply timed out
  virtual void reply_timed_out (void) = 0;

  /// Install the timeout handler
  virtual long schedule_timer (CORBA::ULong ,
                               const ACE_Time_Value &
                               ACE_ENV_ARG_DECL)= 0;

  /// Mutators for refcount
  long incr_refcount (void);
  long decr_refcount (void);

  /// A helper method that can be used by the sublcasses
  /**
   * The semantics of this helper method needs careful attention. A
   * call to this method will do the following
   *
   *   - If the reply has already been dispatched, the return value
   *     will be false to signify not to try.
   *
   *   - If the reply has not been dispatched, this method will set
   *     the flag to be true and return a true value to signify that
   *     the caller thread can go ahead and dispatch reply.
   *
   * Why are we clumping everything in one method. Answer is we need
   * atomicity?
   */
  bool try_dispatch_reply (void);

protected:

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

protected:
  /// The service context list.
  /**
   * Note, that this is not a reference as in
   * the synchronous case. We own the reply_service_info
   * because our TAO_Asynch_Invocation or TAO_DII_Deferred_Invocation
   * will go out of scope before we are done.
   */
  IOP::ServiceContextList reply_service_info_;

  /// The buffer that is used to initialise the data block
  char buf_[ACE_CDR::DEFAULT_BUFSIZE];

  /// Datablock that is created on the stack to initialise the CDR
  /// stream underneath.
  ACE_Data_Block db_;

  /// CDR stream which has the reply information that needs to be
  /// demarshalled by the stubs
  TAO_InputCDR reply_cdr_;

  /// This invocation is using this transport, may change...
  TAO_Transport *transport_;

private:
  /// Lock to protect recount and <is_reply_dispatched_> flag.
  ACE_Lock *lock_;

  /// Refcount paraphernalia for this class
  long refcount_;

  /// Has the reply been dispatched?
  bool is_reply_dispatched_;
};

namespace TAO
{
  /**
   * @class ARDB_Refcount_Functor
   *
   * @brief Functor for refcounting of Asynch_Reply_Dispatcher_Base
   *
   * This is used to safely handle the destruction of
   * Asynch_Reply_Dispatcher_Base objects which are created on the
   * heap. We cannot use auto_ptr <> since it calls delete on the
   * pointer, and calling delete on Asynch_Reply_Dispatcher_Base *
   * will not work. Hence this functor will be used with Auto_Functor
   * class to handle the memory safely.
   *
   * @todo Ideally, this class can be a generic class. But that
   * requires quite a bit of cleanup within TAO to be more useful.
   */
  class TAO_Export ARDB_Refcount_Functor
  {
  public:
    void operator() (TAO_Asynch_Reply_Dispatcher_Base *ardb)
      ACE_THROW_SPEC (());
  };

}

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

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