<?xml version="1.0"?>

<!-- Dispatch Resolution Optimization
 *   ================================
 *   This optimization should be applied with the requests
 *   from a client are delivered to the same operation in
 *   an IDL interface. In general this optimization applies
 *   to IDL interfaces that have a single operation defined
 *   on them
 *
 *   @author Arvind S. Krishna <arvindk@dre.vanderbilt.edu>
 *   $Id: Dispatch-Resolution-Optimization.spl 80826 2008-03-04 14:51:23Z wotte $
-->

<transform>

<module name="TAO/tao">

<file name="Connection_Handler.h">

<!-- Include file to be added for this specialization -->
<add>
 <hook>CONNECTION_HANDLER_SPL_INCLUDE_FORWARD_DECL_ADD_HOOK</hook>
 <data>
   class TAO_Servant_Base;
   #include "tao/Abstract_Servant_Base.h"
 </data>
</add>

<!-- Add get and set operations to hold operation signature -->
<add>
 <hook>CONNECTION_HANDLER_SPL_PRIVATE_DATA_ADD_HOOK</hook>
 <data>
TAO_Skeleton op_signature_;
TAO_Servant_Base *servant_;
 </data>
</add>

<!-- Add get and set public operations for the data -->
<add>
  <hook>CONNECTION_HANDLER_SPL_PUBLIC_METHODS_ADD_HOOK</hook>
  <data>
void set_op_signature (TAO_Skeleton &amp;skeleton,
                       TAO_Servant_Base *&amp;servant);
void get_op_signature (TAO_Skeleton &amp;operation_ptr,
                       TAO_Servant_Base *&amp;servant);
  </data>
</add>

</file>

<file name="Connection_Handler.inl">

<!-- Add operations to get and set the operation signature -->
<add>
 <hook>CONNECTION_HANDLER_SPL_METHODS_ADD_HOOK</hook>
 <data>
  ACE_INLINE void
  TAO_Connection_Handler::set_op_signature (TAO_Skeleton &amp;skeleton,
                                            TAO_Servant_Base *&amp;servant)
{
  this->op_signature_ = skeleton;
  this->servant_ = servant;
}

ACE_INLINE void
TAO_Connection_Handler::get_op_signature (TAO_Skeleton &amp;operation_ptr,
                                          TAO_Servant_Base *&amp;servant)
{
   operation_ptr = this->op_signature_;
   servant = this->servant_;
}

 </data>
</add>
</file>

<file name="GIOP_Message_Base.h">

<add>
<hook>GIOP_MESSAGE_BASE_DATA_MEMBER_ADD_HOOK</hook>
<data>bool once__;</data>
</add>
</file>

<file name="GIOP_Message_Base.cpp">

<add>
 <hook>GIOP_MESSAGE_BASE_INCLUDE_ADD_HOOK</hook>
 <data>#include "tao/Connection_Handler.h"</data>
</add>

<!-- Add a once__ data member to the class that will
     only resolve the dispatch once -->
<substitute match-line="yes">
 <search>TAO_DEF_GIOP_MINOR\)</search>
 <replace>TAO_DEF_GIOP_MINOR)
          , once__ (1)
 </replace>
</substitute>

<!-- Comment code that resolves dispatch normally -->
<comment>
 <start-hook>TAO_DISPATCH_RESOLUTION_OPT_COMMENT_HOOK_START</start-hook>
 <end-hook>TAO_DISPATCH_RESOLUTION_OPT_COMMENT_HOOK_END</end-hook>
</comment>

<!-- Add the optimized path code -->
<add>
 <hook>TAO_DISPATCH_RESOLUTION_OPT_COMMENT_HOOK_END</hook>
 <data>
  if (once__)
  {
    once__ = false;

    // Normal path the first time
    this->orb_core_->request_dispatcher ()->dispatch (
      this->orb_core_,
      request,
      forward_to
      ACE_ENV_ARG_PARAMETER);
    ACE_TRY_CHECK;
  }
  else
  {
    // Dispatch directly to the skeleton
    TAO_Connection_Handler *handler =
      transport->connection_handler ();
    TAO_Skeleton skel;
    TAO_Servant_Base *skeleton_ptr;
    handler->get_op_signature (skel, skeleton_ptr);

    // Convert references to void *
    void *upcall_ptr = 0;
    skel (request,
          upcall_ptr,
          (void *)skeleton_ptr
          ACE_ENV_ARG_PARAMETER);
    if (response_required)
      request.tao_send_reply ();
  }
 </data>
</add>
</file>
</module>

<module name="TAO/tao/PortableServer">
<file name="Servant_Base.cpp">

<!-- Add necessary include files -->
<add>
 <hook>TAO_SERVANT_BASE_INCLUDE_ADD_HOOK</hook>
 <data>#include "tao/Transport.h"</data>
 <data>#include "tao/Connection_Handler.h"</data>
</add>

<!-- After processing the first request, set the operation signature on
     the connection handler for subsequent request processing -->
<add>
 <hook>TAO_DISPATCH_RESOLUTION_OPT_ADD_HOOK</hook>
 <data>
   TAO_Connection_Handler *handler =
   req.transport ()->connection_handler ();
   handler->set_op_signature (skel,
                              static_cast&lt;TAO_Servant_Base *&gt; (derived_this));
 </data>
</add>
</file>

</module>

</transform>
