TAO_SHMIOP_Transport Class Reference

Specialization of the base TAO_Transport class to handle the SHMIOP protocol. More...

#include <SHMIOP_Transport.h>

Inheritance diagram for TAO_SHMIOP_Transport:

Inheritance graph
[legend]
Collaboration diagram for TAO_SHMIOP_Transport:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 TAO_SHMIOP_Transport (TAO_SHMIOP_Connection_Handler *handler, TAO_ORB_Core *orb_core)
 Constructor.
 ~TAO_SHMIOP_Transport (void)
 Default destructor.
virtual int send_request (TAO_Stub *stub, TAO_ORB_Core *orb_core, TAO_OutputCDR &stream, TAO_Message_Semantics message_semantics, ACE_Time_Value *max_wait_time)
virtual int send_message (TAO_OutputCDR &stream, TAO_Stub *stub=0, TAO_Message_Semantics message_semantics=TAO_Transport::TAO_TWOWAY_REQUEST, ACE_Time_Value *max_time_wait=0)

Protected Member Functions

Overridden Template Methods
These are implementations of template methods declared by TAO_Transport.

virtual ACE_Event_Handlerevent_handler_i (void)
virtual TAO_Connection_Handlerconnection_handler_i (void)
virtual ssize_t send (iovec *iov, int iovcnt, size_t &bytes_transferred, const ACE_Time_Value *timeout=0)
 Write the complete Message_Block chain to the connection.
virtual ssize_t recv (char *buf, size_t len, const ACE_Time_Value *s=0)
 Read len bytes from into buf.
virtual int handle_input (TAO_Resume_Handle &rh, ACE_Time_Value *max_wait_time)

Private Attributes

TAO_SHMIOP_Connection_Handlerconnection_handler_

Detailed Description

Specialization of the base TAO_Transport class to handle the SHMIOP protocol.

Definition at line 53 of file SHMIOP_Transport.h.


Constructor & Destructor Documentation

TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO_SHMIOP_Transport::TAO_SHMIOP_Transport ( TAO_SHMIOP_Connection_Handler handler,
TAO_ORB_Core orb_core 
)

Constructor.

Definition at line 24 of file SHMIOP_Transport.cpp.

00026   : TAO_Transport (TAO_TAG_SHMEM_PROFILE,
00027                    orb_core),
00028     connection_handler_ (handler)
00029 {
00030 }

TAO_SHMIOP_Transport::~TAO_SHMIOP_Transport ( void   ) 

Default destructor.

Definition at line 32 of file SHMIOP_Transport.cpp.

00033 {
00034 }


Member Function Documentation

TAO_Connection_Handler * TAO_SHMIOP_Transport::connection_handler_i ( void   )  [protected, virtual]

Implements TAO_Transport.

Definition at line 43 of file SHMIOP_Transport.cpp.

References connection_handler_.

00044 {
00045   return this->connection_handler_;
00046 }

ACE_Event_Handler * TAO_SHMIOP_Transport::event_handler_i ( void   )  [protected, virtual]

Implements TAO_Transport.

Definition at line 37 of file SHMIOP_Transport.cpp.

References connection_handler_.

00038 {
00039   return this->connection_handler_;
00040 }

int TAO_SHMIOP_Transport::handle_input ( TAO_Resume_Handle rh,
ACE_Time_Value max_wait_time 
) [protected, virtual]

Reimplemented from TAO_Transport.

Definition at line 112 of file SHMIOP_Transport.cpp.

References ACE_DEBUG, ACE_ERROR, ACE_Message_Block::DONT_DELETE, ACE_CDR::grow(), TAO_GIOP_Message_Base::header_length(), TAO_ORB_Core::input_cdr_dblock_allocator(), LM_DEBUG, LM_ERROR, TAO_ORB_Core::locking_strategy(), ACE_CDR::MAX_ALIGNMENT, ACE_CDR::mb_align(), ACE_Message_Block::MB_DATA, ACE_OS::memset(), TAO_Transport::messaging_object(), TAO_Queued_Data::missing_data(), TAO_Transport::orb_core_, recv(), TAO_debug_level, TAO_MAXBUFSIZE, and TAO_MISSING_DATA_UNDEFINED.

00114 {
00115   if (TAO_debug_level > 3)
00116     {
00117       ACE_DEBUG ((LM_DEBUG,
00118                   "TAO (%P|%t) - SHMIOP_Transport[%d]::handle_input\n",
00119                   this->id ()));
00120     }
00121 
00122    // The buffer on the stack which will be used to hold the input
00123   // messages, compensate shrink due to alignment
00124   char buf [TAO_MAXBUFSIZE + ACE_CDR::MAX_ALIGNMENT];
00125 
00126 
00127 #if defined (ACE_INITIALIZE_MEMORY_BEFORE_USE)
00128   (void) ACE_OS::memset (buf,
00129                          '\0',
00130                          sizeof buf);
00131 #endif /* ACE_INITIALIZE_MEMORY_BEFORE_USE */
00132 
00133   // Create a data block
00134   ACE_Data_Block db (sizeof (buf),
00135                      ACE_Message_Block::MB_DATA,
00136                      buf,
00137                      this->orb_core_->input_cdr_buffer_allocator (),
00138                      this->orb_core_->locking_strategy (),
00139                      ACE_Message_Block::DONT_DELETE,
00140                      this->orb_core_->input_cdr_dblock_allocator ());
00141 
00142   // Create a message block
00143   ACE_Message_Block message_block (&db,
00144                                    ACE_Message_Block::DONT_DELETE,
00145                                    this->orb_core_->input_cdr_msgblock_allocator ());
00146 
00147 
00148   // Align the message block
00149   ACE_CDR::mb_align (&message_block);
00150 
00151   const size_t missing_header_data = this->messaging_object ()->header_length ();
00152 
00153   if (missing_header_data == 0)
00154     {
00155       return -1;
00156     }
00157 
00158   // .. do a read on the socket again.
00159   ssize_t bytes = 0;
00160 
00161   // As this used for transports where things are available in one
00162   // shot this looping should not create any problems.
00163   for (size_t m = missing_header_data;
00164        m != 0;
00165        m -= bytes)
00166     {
00167       bytes = 0; // reset
00168 
00169       // We would have liked to use something like a recv_n ()
00170       // here. But at the time when the code was written, the MEM_Stream
00171       // classes had poor support  for recv_n (). Till a day when we
00172       // get proper recv_n (), let us stick with this. The other
00173       // argument that can be said against this is that, this is the
00174       // bad layer in which this is being done ie. recv_n is
00175       // simulated. But...
00176       bytes = this->recv (message_block.wr_ptr (),
00177                           m,
00178                           max_wait_time);
00179 
00180       if (bytes == 0 ||
00181           bytes == -1)
00182         {
00183           return -1;
00184         }
00185 
00186       message_block.wr_ptr (bytes);
00187     }
00188 
00189     TAO_Queued_Data qd (&message_block);
00190     size_t mesg_length = 0;
00191 
00192     // Parse the incoming message for validity. The check needs to be
00193     // performed by the messaging objects.
00194     if (this->messaging_object ()->parse_next_message (qd,
00195                                                        mesg_length) == -1)
00196       return -1;
00197 
00198     if (qd.missing_data () == TAO_MISSING_DATA_UNDEFINED)
00199       {
00200         // parse/marshal error happened
00201         return -1;
00202       }
00203 
00204     if (message_block.length () > mesg_length)
00205       {
00206         // we read too much data
00207         return -1;
00208       }
00209 
00210     if (message_block.space () < qd.missing_data ())
00211       {
00212         size_t const message_size = message_block.length ()
00213                                   + qd.missing_data ();
00214 
00215         // reallocate buffer with correct size on heap
00216         if (ACE_CDR::grow (&message_block, message_size) == -1)
00217           {
00218             if (TAO_debug_level > 0)
00219               {
00220                 ACE_ERROR ((LM_ERROR,
00221                  "TAO (%P|%t) - SHMIOP_Transport[%d]::handle_input, "
00222                  "error growing message buffer\n",
00223                  this->id () ));
00224               }
00225             return -1;
00226           }
00227 
00228       }
00229 
00230     // As this used for transports where things are available in one
00231     // shot this looping should not create any problems.
00232     for (size_t n = qd.missing_data ();
00233        n != 0;
00234        n -= bytes)
00235     {
00236         bytes = 0; // reset
00237 
00238       // We would have liked to use something like a recv_n ()
00239       // here. But at the time when the code was written, the MEM_Stream
00240       // classes had poor support  for recv_n (). Till a day when we
00241       // get proper recv_n (), let us stick with this. The other
00242       // argument that can be said against this is that, this is the
00243       // bad layer in which this is being done ie. recv_n is
00244       // simulated. But...
00245       bytes = this->recv (message_block.wr_ptr (),
00246                           n,
00247                           max_wait_time);
00248 
00249       if (bytes == 0 ||
00250           bytes == -1)
00251         {
00252           return -1;
00253         }
00254 
00255       message_block.wr_ptr (bytes);
00256     }
00257 
00258   qd.missing_data (0);
00259 
00260   // Now we have a full message in our buffer. Just go ahead and
00261   // process that
00262   if (this->process_parsed_messages (&qd, rh) == -1)
00263     {
00264       return -1;
00265     }
00266 
00267   return 0;
00268 }

ssize_t TAO_SHMIOP_Transport::recv ( char *  buf,
size_t  len,
const ACE_Time_Value s = 0 
) [protected, virtual]

Read len bytes from into buf.

Implements TAO_Transport.

Definition at line 69 of file SHMIOP_Transport.cpp.

References ACE_DEBUG, ACE_TEXT, connection_handler_, LM_DEBUG, ACE_Svc_Handler<, >::peer(), and TAO_debug_level.

Referenced by handle_input().

00072 {
00073   ssize_t n = 0;
00074 
00075   int read_break = 0;
00076 
00077   while (!read_break)
00078     {
00079       n = this->connection_handler_->peer ().recv (buf,
00080                                                    len,
00081                                                    max_wait_time);
00082 
00083       // If we get a EWOULBLOCK we try to read again.
00084       if (n == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
00085         {
00086           n = 0;
00087           continue;
00088         }
00089 
00090       // If there is anything else we just drop out of the loop.
00091       read_break = 1;
00092     }
00093 
00094   if (n == -1)
00095     {
00096       if (TAO_debug_level > 3 && errno != ETIME)
00097         {
00098           ACE_DEBUG ((LM_DEBUG,
00099                       ACE_TEXT ("TAO (%P|%t) -  SHMIOP_Transport::recv, %p \n"),
00100                       ACE_TEXT ("TAO - read message failure ")
00101                       ACE_TEXT ("recv_i () \n")));
00102         }
00103     }
00104   else if (n == 0)
00105     {
00106       n = -1;
00107     }
00108   return n;
00109 }

ssize_t TAO_SHMIOP_Transport::send ( iovec *  iov,
int  iovcnt,
size_t &  bytes_transferred,
const ACE_Time_Value timeout = 0 
) [protected, virtual]

Write the complete Message_Block chain to the connection.

Implements TAO_Transport.

Definition at line 49 of file SHMIOP_Transport.cpp.

00052 {
00053   bytes_transferred = 0;
00054   for (int i = 0; i < iovcnt; ++i)
00055     {
00056       ssize_t retval =
00057         this->connection_handler_->peer ().send (iov[i].iov_base,
00058                                                  iov[i].iov_len,
00059                                                  max_wait_time);
00060       if (retval > 0)
00061         bytes_transferred += retval;
00062       if (retval <= 0)
00063         return retval;
00064     }
00065   return bytes_transferred;
00066 }

int TAO_SHMIOP_Transport::send_message ( TAO_OutputCDR stream,
TAO_Stub stub = 0,
TAO_Message_Semantics  message_semantics = TAO_Transport::TAO_TWOWAY_REQUEST,
ACE_Time_Value max_time_wait = 0 
) [virtual]

Definition at line 295 of file SHMIOP_Transport.cpp.

References ACE_DEBUG, ACE_TEXT, ACE_OutputCDR::begin(), LM_DEBUG, TAO_Transport::send_message_shared(), and TAO_debug_level.

00299 {
00300   // Format the message in the stream first
00301   if (this->messaging_object_->format_message (stream) != 0)
00302     return -1;
00303 
00304   // Strictly speaking, should not need to loop here because the
00305   // socket never gets set to a nonblocking mode ... some Linux
00306   // versions seem to need it though.  Leaving it costs little.
00307 
00308   // This guarantees to send all data (bytes) or return an error.
00309   ssize_t n = this->send_message_shared (stub,
00310                                          message_semantics,
00311                                          stream.begin (),
00312                                          max_wait_time);
00313 
00314   if (n == -1)
00315     {
00316       if (TAO_debug_level)
00317         ACE_DEBUG ((LM_DEBUG,
00318                     ACE_TEXT ("TAO (%P|%t) closing transport %d after fault %p\n"),
00319                     this->id (),
00320                     ACE_TEXT ("send_message ()\n")));
00321 
00322       return -1;
00323     }
00324 
00325   return 1;
00326 }

int TAO_SHMIOP_Transport::send_request ( TAO_Stub stub,
TAO_ORB_Core orb_core,
TAO_OutputCDR stream,
TAO_Message_Semantics  message_semantics,
ACE_Time_Value max_wait_time 
) [virtual]

Todo:
These methods IMHO should have more meaningful names. The names seem to indicate nothing.

Definition at line 273 of file SHMIOP_Transport.cpp.

References TAO_Transport::first_request_sent(), and TAO_Transport::orb_core().

00278 {
00279   if (this->ws_->sending_request (orb_core,
00280                                   message_semantics) == -1)
00281     return -1;
00282 
00283   if (this->send_message (stream,
00284                           stub,
00285                           message_semantics,
00286                           max_wait_time) == -1)
00287 
00288     return -1;
00289   this->first_request_sent();
00290 
00291   return 0;
00292 }


Member Data Documentation

TAO_SHMIOP_Connection_Handler* TAO_SHMIOP_Transport::connection_handler_ [private]

The connection service handler used for accessing lower layer communication protocols.

Definition at line 105 of file SHMIOP_Transport.h.

Referenced by connection_handler_i(), event_handler_i(), and recv().


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:47:34 2010 for TAO_Strategies by  doxygen 1.4.7