1 #include "tao/Muxed_TMS.h"
2 #include "tao/Reply_Dispatcher.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
)
13 , request_id_generator_ (0)
14 , orb_core_ (transport
->orb_core ())
15 , dispatcher_table_ (this->orb_core_
->client_factory ()->reply_dispatcher_table_size ())
18 this->orb_core_
->client_factory ()->create_transport_mux_strategy_lock ();
21 TAO_Muxed_TMS::~TAO_Muxed_TMS ()
26 // Generate and return an unique request id for the current
29 TAO_Muxed_TMS::request_id ()
31 // @@ What is a good error return value?
32 ACE_GUARD_RETURN (ACE_Lock
,
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.
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
,
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")));
81 int const result
= this->dispatcher_table_
.bind (request_id
, rd
);
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"),
98 TAO_Muxed_TMS::unbind_dispatcher (CORBA::ULong request_id
)
100 ACE_GUARD_RETURN (ACE_Lock
,
105 return this->dispatcher_table_
.unbind (request_id
);
109 TAO_Muxed_TMS::has_request ()
111 ACE_GUARD_RETURN (ACE_Lock
,
116 return this->dispatcher_table_
.current_size () > 0;
120 TAO_Muxed_TMS::dispatch_reply (TAO_Pluggable_Reply_Params
¶ms
)
123 ACE_Intrusive_Auto_Ptr
<TAO_Reply_Dispatcher
> rd(nullptr);
125 // Grab the reply dispatcher for this id.
127 ACE_GUARD_RETURN (ACE_Lock
,
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
);
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"),
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.
167 TAO_Muxed_TMS::reply_timed_out (CORBA::ULong request_id
)
170 ACE_Intrusive_Auto_Ptr
<TAO_Reply_Dispatcher
> rd(nullptr);
172 // Grab the reply dispatcher for this id.
174 ACE_GUARD_RETURN (ACE_Lock
,
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"),
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 ();
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"),
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.
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 ();
233 TAO_Muxed_TMS::idle_after_reply ()
239 TAO_Muxed_TMS::connection_closed ()
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)
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 ();
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 ();
288 TAO_END_VERSIONED_NAMESPACE_DECL