Merge pull request #2301 from sonndinh/remove-dup-reactor-functions
[ACE_TAO.git] / TAO / tao / Muxed_TMS.cpp
blobc80043ad54133ff75d6560467d795aa21718ceb5
1 #include "tao/Muxed_TMS.h"
2 #include "tao/Reply_Dispatcher.h"
3 #include "tao/debug.h"
4 #include "tao/Transport.h"
5 #include "tao/ORB_Core.h"
6 #include "tao/Client_Strategy_Factory.h"
8 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
10 TAO_Muxed_TMS::TAO_Muxed_TMS (TAO_Transport *transport)
11 : TAO_Transport_Mux_Strategy (transport)
12 , lock_ (nullptr)
13 , request_id_generator_ (0)
14 , orb_core_ (transport->orb_core ())
15 , dispatcher_table_ (this->orb_core_->client_factory ()->reply_dispatcher_table_size ())
17 this->lock_ =
18 this->orb_core_->client_factory ()->create_transport_mux_strategy_lock ();
21 TAO_Muxed_TMS::~TAO_Muxed_TMS ()
23 delete this->lock_;
26 // Generate and return an unique request id for the current
27 // invocation.
28 CORBA::ULong
29 TAO_Muxed_TMS::request_id ()
31 // @@ What is a good error return value?
32 ACE_GUARD_RETURN (ACE_Lock,
33 ace_mon,
34 *this->lock_,
35 0);
37 ++this->request_id_generator_;
39 // if TAO_Transport::bidirectional_flag_
40 // == 1 --> originating side
41 // == 0 --> other side
42 // == -1 --> no bi-directional connection was negotiated
43 // The originating side must have an even request ID, and the other
44 // side must have an odd request ID. Make sure that is the case.
45 int const bidir_flag = this->transport_->bidirectional_flag ();
47 if ((bidir_flag == 1 && ACE_ODD (this->request_id_generator_))
48 || (bidir_flag == 0 && ACE_EVEN (this->request_id_generator_)))
49 ++this->request_id_generator_;
51 if (TAO_debug_level > 4)
52 TAOLIB_DEBUG ((LM_DEBUG,
53 "TAO (%P|%t) - Muxed_TMS[%d]::request_id, [%d]\n",
54 this->transport_->id (),
55 this->request_id_generator_));
57 return this->request_id_generator_;
60 /// Bind the dispatcher with the request id.
61 int
62 TAO_Muxed_TMS::bind_dispatcher (CORBA::ULong request_id,
63 ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd)
65 ACE_GUARD_RETURN (ACE_Lock,
66 ace_mon,
67 *this->lock_,
68 -1);
70 if (rd == nullptr)
72 if (TAO_debug_level > 0)
74 TAOLIB_DEBUG ((LM_DEBUG,
75 ACE_TEXT ("TAO (%P|%t) - TAO_Muxed_TMS::bind_dispatcher, ")
76 ACE_TEXT ("null reply dispatcher\n")));
78 return 0;
81 int const result = this->dispatcher_table_.bind (request_id, rd);
83 if (result != 0)
85 if (TAO_debug_level > 0)
86 TAOLIB_ERROR ((LM_ERROR,
87 ACE_TEXT ("TAO (%P|%t) - TAO_Muxed_TMS::bind_dispatcher, ")
88 ACE_TEXT ("bind dispatcher failed: result = %d, request id [%d]\n"),
89 result, request_id));
91 return -1;
94 return 0;
97 int
98 TAO_Muxed_TMS::unbind_dispatcher (CORBA::ULong request_id)
100 ACE_GUARD_RETURN (ACE_Lock,
101 ace_mon,
102 *this->lock_,
103 -1);
105 return this->dispatcher_table_.unbind (request_id);
108 bool
109 TAO_Muxed_TMS::has_request ()
111 ACE_GUARD_RETURN (ACE_Lock,
112 ace_mon,
113 *this->lock_,
114 false);
116 return this->dispatcher_table_.current_size () > 0;
120 TAO_Muxed_TMS::dispatch_reply (TAO_Pluggable_Reply_Params &params)
122 int result = 0;
123 ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd(nullptr);
125 // Grab the reply dispatcher for this id.
127 ACE_GUARD_RETURN (ACE_Lock,
128 ace_mon,
129 *this->lock_,
130 -1);
131 result = this->dispatcher_table_.unbind (params.request_id_, rd);
134 if (result == 0 && rd)
136 if (TAO_debug_level > 8)
137 TAOLIB_DEBUG ((LM_DEBUG,
138 ACE_TEXT ("TAO (%P|%t) - TAO_Muxed_TMS::dispatch_reply, ")
139 ACE_TEXT ("id [%d]\n"),
140 params.request_id_));
142 // Dispatch the reply.
143 // They return 1 on success, and -1 on failure.
144 result = rd->dispatch_reply (params);
146 else
148 if (TAO_debug_level > 0)
149 TAOLIB_DEBUG ((LM_DEBUG,
150 ACE_TEXT ("TAO (%P|%t) - TAO_Muxed_TMS::dispatch_reply, ")
151 ACE_TEXT ("unbind dispatcher failed, id [%d], result = %d\n"),
152 params.request_id_,
153 result));
155 // Result = 0 means that the mux strategy was not able
156 // to find a registered reply handler, either because the reply
157 // was not our reply - just forget about it - or it was ours, but
158 // the reply timed out - just forget about the reply.
159 result = 0;
163 return result;
167 TAO_Muxed_TMS::reply_timed_out (CORBA::ULong request_id)
169 int result = 0;
170 ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd(nullptr);
172 // Grab the reply dispatcher for this id.
174 ACE_GUARD_RETURN (ACE_Lock,
175 ace_mon,
176 *this->lock_,
177 -1);
179 result = this->dispatcher_table_.unbind (request_id, rd);
182 if (result == 0 && rd)
184 if (TAO_debug_level > 8)
186 TAOLIB_DEBUG ((LM_DEBUG,
187 ACE_TEXT ("TAO (%P|%t) - TAO_Muxed_TMS::reply_timed_out, ")
188 ACE_TEXT ("id [%d]\n"),
189 request_id));
192 // Do not move it outside the scope of the lock. A follower thread
193 // could have timedout unwinding the stack and the reply
194 // dispatcher, and that would mean the present thread could be left
195 // with a dangling pointer and may crash. To safeguard against such
196 // cases we dispatch with the lock held.
197 // Dispatch the reply.
198 rd->reply_timed_out ();
200 else
202 if (TAO_debug_level > 0)
203 TAOLIB_DEBUG ((LM_DEBUG,
204 ACE_TEXT ("TAO (%P|%t) - TAO_Muxed_TMS::reply_timed_out, ")
205 ACE_TEXT ("unbind dispatcher failed, id [%d] result = %d\n"),
206 request_id,
207 result));
209 // Result = 0 means that the mux strategy was not able
210 // to find a registered reply handler, either because the reply
211 // was not our reply - just forget about it - or it was ours, but
212 // the reply timed out - just forget about the reply.
213 result = 0;
216 return result;
220 bool
221 TAO_Muxed_TMS::idle_after_send ()
223 // Irrespective of whether we are successful or not we need to
224 // return true. If *this* class is not successful in idling the
225 // transport no one can.
226 if (this->transport_ != nullptr)
227 (void) this->transport_->make_idle ();
229 return true;
232 bool
233 TAO_Muxed_TMS::idle_after_reply ()
235 return false;
238 void
239 TAO_Muxed_TMS::connection_closed ()
241 ACE_GUARD (ACE_Lock,
242 ace_mon,
243 *this->lock_);
245 int retval = 0;
248 retval = this->clear_cache_i ();
250 while (retval != -1);
254 TAO_Muxed_TMS::clear_cache_i ()
256 if (this->dispatcher_table_.current_size () == 0)
257 return -1;
259 REQUEST_DISPATCHER_TABLE::ITERATOR const end =
260 this->dispatcher_table_.end ();
262 ACE_Unbounded_Stack <ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> > ubs;
264 for (REQUEST_DISPATCHER_TABLE::ITERATOR i =
265 this->dispatcher_table_.begin ();
266 i != end;
267 ++i)
269 ubs.push ((*i).int_id_);
272 this->dispatcher_table_.unbind_all ();
273 size_t const sz = ubs.size ();
275 for (size_t k = 0 ; k != sz ; ++k)
277 ACE_Intrusive_Auto_Ptr<TAO_Reply_Dispatcher> rd(nullptr);
279 if (ubs.pop (rd) == 0)
281 rd->connection_closed ();
285 return 0;
288 TAO_END_VERSIONED_NAMESPACE_DECL