Muxed_TMS.cpp

Go to the documentation of this file.
00001 // Muxed_TMS.cpp,v 1.31 2006/03/10 07:19:05 jtc Exp
00002 
00003 #include "tao/Muxed_TMS.h"
00004 #include "tao/Reply_Dispatcher.h"
00005 #include "tao/debug.h"
00006 #include "tao/Transport.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/Client_Strategy_Factory.h"
00009 
00010 ACE_RCSID (tao,
00011            Muxed_TMS,
00012            "Muxed_TMS.cpp,v 1.31 2006/03/10 07:19:05 jtc Exp")
00013 
00014 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00015 
00016 TAO_Muxed_TMS::TAO_Muxed_TMS (TAO_Transport *transport)
00017   : TAO_Transport_Mux_Strategy (transport)
00018     , request_id_generator_ (0)
00019     , orb_core_ (transport->orb_core ())
00020     , dispatcher_table_ (this->orb_core_->client_factory ()->reply_dispatcher_table_size ())
00021 {
00022   this->lock_ =
00023     this->orb_core_->client_factory ()->create_transport_mux_strategy_lock ();
00024 }
00025 
00026 TAO_Muxed_TMS::~TAO_Muxed_TMS (void)
00027 {
00028   delete this->lock_;
00029 }
00030 
00031 // Generate and return an unique request id for the current
00032 // invocation.
00033 CORBA::ULong
00034 TAO_Muxed_TMS::request_id (void)
00035 {
00036   // @@ What is a good error return value?
00037   ACE_GUARD_RETURN (ACE_Lock,
00038                     ace_mon,
00039                     *this->lock_,
00040                     0);
00041 
00042   ++this->request_id_generator_;
00043 
00044   // if TAO_Transport::bidirectional_flag_
00045   //  ==  1 --> originating side
00046   //  ==  0 --> other side
00047   //  == -1 --> no bi-directional connection was negotiated
00048   // The originating side must have an even request ID, and the other
00049   // side must have an odd request ID.  Make sure that is the case.
00050   int bidir_flag =
00051     this->transport_->bidirectional_flag ();
00052 
00053   if ((bidir_flag == 1 && ACE_ODD (this->request_id_generator_))
00054        || (bidir_flag == 0 && ACE_EVEN (this->request_id_generator_)))
00055     ++this->request_id_generator_;
00056 
00057   if (TAO_debug_level > 4)
00058     ACE_DEBUG ((LM_DEBUG,
00059                 "TAO (%P|%t) - Muxed_TMS[%d]::request_id, <%d>\n",
00060                 this->transport_->id (),
00061                 this->request_id_generator_));
00062 
00063   return this->request_id_generator_;
00064 }
00065 
00066 // Bind the dispatcher with the request id.
00067 int
00068 TAO_Muxed_TMS::bind_dispatcher (CORBA::ULong request_id,
00069                                 TAO_Reply_Dispatcher *rd)
00070 {
00071   ACE_GUARD_RETURN (ACE_Lock,
00072                     ace_mon,
00073                     *this->lock_,
00074                     -1);
00075 
00076   if (TAO_debug_level > 0 && rd == 0)
00077     ACE_DEBUG ((LM_DEBUG,
00078                 ACE_TEXT ("TAO (%P|%t) - TAO_Muxed_TMS::bind_dispatcher, ")
00079                 ACE_TEXT ("null reply dispatcher\n")));
00080 
00081   if (rd == 0)
00082     return 0;
00083 
00084   int result =
00085     this->dispatcher_table_.bind (request_id, rd);
00086 
00087 
00088   if (result != 0)
00089     {
00090       if (TAO_debug_level > 0)
00091         ACE_DEBUG ((LM_DEBUG,
00092                     ACE_TEXT ("TAO (%P|%t) - TAO_Muxed_TMS::bind_dispatcher, ")
00093                     ACE_TEXT ("bind dispatcher failed: result = %d, request id = %d \n"),
00094                     result, request_id));
00095 
00096       return -1;
00097     }
00098 
00099   return 0;
00100 }
00101 
00102 int
00103 TAO_Muxed_TMS::unbind_dispatcher (CORBA::ULong request_id)
00104 {
00105   ACE_GUARD_RETURN (ACE_Lock,
00106                     ace_mon,
00107                     *this->lock_,
00108                     -1);
00109   TAO_Reply_Dispatcher *rd = 0;
00110 
00111   // @@TODO: WTH are we sending the rd in? We can just unbind using
00112   // the request_id
00113   return this->dispatcher_table_.unbind (request_id, rd);
00114 }
00115 
00116 int
00117 TAO_Muxed_TMS::dispatch_reply (TAO_Pluggable_Reply_Params &params)
00118 {
00119   int result = 0;
00120   TAO_Reply_Dispatcher *rd = 0;
00121 
00122   // Grab the reply dispatcher for this id.
00123   {
00124     ACE_GUARD_RETURN (ACE_Lock,
00125                       ace_mon,
00126                       *this->lock_,
00127                       -1);
00128 
00129     result =
00130       this->dispatcher_table_.unbind (params.request_id_, rd);
00131 
00132     if (TAO_debug_level > 8)
00133       ACE_DEBUG ((LM_DEBUG,
00134                   ACE_TEXT ("TAO (%P|%t) - TAO_Muxed_TMS::dispatch_reply, ")
00135                   ACE_TEXT ("id = %d\n"),
00136                   params.request_id_));
00137 
00138     if (result != 0)
00139       {
00140         if (TAO_debug_level > 0)
00141           ACE_DEBUG ((LM_DEBUG,
00142                       ACE_TEXT ("TAO (%P|%t) - TAO_Muxed_TMS::dispatch_reply, ")
00143                       ACE_TEXT ("unbind dispatcher failed: result = %d\n"),
00144                       result));
00145 
00146         // This return value means that the mux strategy was not able
00147         // to find a registered reply handler, either because the reply
00148         // was not our reply - just forget about it - or it was ours, but
00149         // the reply timed out - just forget about the reply.
00150         return 0;
00151       }
00152 
00153     // Do not move it outside the scope of the lock. A follower thread
00154     // could have timedout unwinding the stack and the reply
00155     // dispatcher, and that would mean the present thread could be left
00156     // with a dangling pointer and may crash. To safeguard againt such
00157     // cases we dispatch with the lock held.
00158     // Dispatch the reply.
00159     // They return 1 on success, and -1 on failure.
00160     result =  rd->dispatch_reply (params);
00161   }
00162 
00163   return result;
00164 }
00165 
00166 bool
00167 TAO_Muxed_TMS::idle_after_send (void)
00168 {
00169   // Irrespective of whether we are successful or not we need to
00170   // return true. If *this* class is not successfull in idling the
00171   // transport no one can.
00172   if (this->transport_ != 0)
00173     (void) this->transport_->make_idle ();
00174 
00175   return true;
00176 }
00177 
00178 bool
00179 TAO_Muxed_TMS::idle_after_reply (void)
00180 {
00181   return false;
00182 }
00183 
00184 void
00185 TAO_Muxed_TMS::connection_closed (void)
00186 {
00187   ACE_GUARD (ACE_Lock,
00188              ace_mon,
00189              *this->lock_);
00190 
00191   int retval = 0;
00192   do
00193     {
00194       retval = this->clear_cache ();
00195     }
00196   while (retval != -1);
00197 
00198 }
00199 
00200 int
00201 TAO_Muxed_TMS::clear_cache (void)
00202 {
00203   if (this->dispatcher_table_.current_size () == 0)
00204     return -1;
00205 
00206   REQUEST_DISPATCHER_TABLE::ITERATOR const end =
00207     this->dispatcher_table_.end ();
00208 
00209   ACE_Unbounded_Stack <TAO_Reply_Dispatcher *> ubs;
00210 
00211   for (REQUEST_DISPATCHER_TABLE::ITERATOR i =
00212          this->dispatcher_table_.begin ();
00213        i != end;
00214        ++i)
00215       ubs.push ((*i).int_id_);
00216 
00217   this->dispatcher_table_.unbind_all ();
00218   size_t const sz = ubs.size ();
00219 
00220   for (size_t k = 0 ; k != sz ; ++k)
00221     {
00222       TAO_Reply_Dispatcher *rd = 0;
00223 
00224       ubs.pop (rd);
00225 
00226       rd->connection_closed ();
00227     }
00228 
00229   return 0;
00230 }
00231 
00232 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 11:54:16 2006 for TAO by doxygen 1.3.6