1 #include "tao/Strategies/SHMIOP_Transport.h"
3 #if defined (TAO_HAS_SHMIOP) && (TAO_HAS_SHMIOP != 0)
5 #include "tao/Strategies/SHMIOP_Connection_Handler.h"
6 #include "tao/Strategies/SHMIOP_Profile.h"
7 #include "tao/Timeprobe.h"
9 #include "tao/Transport_Mux_Strategy.h"
10 #include "tao/Wait_Strategy.h"
12 #include "tao/ORB_Core.h"
13 #include "tao/debug.h"
14 #include "tao/Resume_Handle.h"
15 #include "tao/GIOP_Message_Base.h"
17 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
19 TAO_SHMIOP_Transport::TAO_SHMIOP_Transport (TAO_SHMIOP_Connection_Handler
*handler
,
20 TAO_ORB_Core
*orb_core
)
21 : TAO_Transport (TAO_TAG_SHMEM_PROFILE
,
23 connection_handler_ (handler
)
27 TAO_SHMIOP_Transport::~TAO_SHMIOP_Transport ()
32 TAO_SHMIOP_Transport::event_handler_i ()
34 return this->connection_handler_
;
37 TAO_Connection_Handler
*
38 TAO_SHMIOP_Transport::connection_handler_i ()
40 return this->connection_handler_
;
44 TAO_SHMIOP_Transport::send (iovec
*iov
, int iovcnt
,
45 size_t &bytes_transferred
,
46 const ACE_Time_Value
*max_wait_time
)
48 bytes_transferred
= 0;
49 for (int i
= 0; i
< iovcnt
; ++i
)
52 this->connection_handler_
->peer ().send (iov
[i
].iov_base
,
56 bytes_transferred
+= retval
;
60 return bytes_transferred
;
64 TAO_SHMIOP_Transport::recv (char *buf
,
66 const ACE_Time_Value
*max_wait_time
)
74 n
= this->connection_handler_
->peer ().recv (buf
,
78 // If we get a EWOULBLOCK we try to read again.
79 if (n
== -1 && (errno
== EAGAIN
|| errno
== EWOULDBLOCK
))
85 // If there is anything else we just drop out of the loop.
91 if (TAO_debug_level
> 3 && errno
!= ETIME
)
93 TAOLIB_DEBUG ((LM_DEBUG
,
94 ACE_TEXT ("TAO (%P|%t) - SHMIOP_Transport::recv, %p\n"),
95 ACE_TEXT ("TAO - read message failure ")
96 ACE_TEXT ("recv_i ()\n")));
107 TAO_SHMIOP_Transport::handle_input (TAO_Resume_Handle
&rh
,
108 ACE_Time_Value
*max_wait_time
)
110 if (TAO_debug_level
> 3)
112 TAOLIB_DEBUG ((LM_DEBUG
,
113 "TAO (%P|%t) - SHMIOP_Transport[%d]::handle_input\n",
117 // The buffer on the stack which will be used to hold the input
118 // messages, compensate shrink due to alignment
119 char buf
[TAO_MAXBUFSIZE
+ ACE_CDR::MAX_ALIGNMENT
];
122 #if defined (ACE_INITIALIZE_MEMORY_BEFORE_USE)
123 (void) ACE_OS::memset (buf
,
126 #endif /* ACE_INITIALIZE_MEMORY_BEFORE_USE */
128 // Create a data block
129 ACE_Data_Block
db (sizeof (buf
),
130 ACE_Message_Block::MB_DATA
,
132 this->orb_core_
->input_cdr_buffer_allocator (),
133 this->orb_core_
->locking_strategy (),
134 ACE_Message_Block::DONT_DELETE
,
135 this->orb_core_
->input_cdr_dblock_allocator ());
137 // Create a message block
138 ACE_Message_Block
message_block (&db
,
139 ACE_Message_Block::DONT_DELETE
,
140 this->orb_core_
->input_cdr_msgblock_allocator ());
143 // Align the message block
144 ACE_CDR::mb_align (&message_block
);
146 const size_t missing_header_data
= this->messaging_object ()->header_length ();
148 if (missing_header_data
== 0)
153 // .. do a read on the socket again.
156 // As this used for transports where things are available in one
157 // shot this looping should not create any problems.
158 for (size_t m
= missing_header_data
;
164 // We would have liked to use something like a recv_n ()
165 // here. But at the time when the code was written, the MEM_Stream
166 // classes had poor support for recv_n (). Till a day when we
167 // get proper recv_n (), let us stick with this. The other
168 // argument that can be said against this is that, this is the
169 // bad layer in which this is being done ie. recv_n is
171 bytes
= this->recv (message_block
.wr_ptr (),
181 message_block
.wr_ptr (bytes
);
184 TAO_Queued_Data
qd (&message_block
);
185 size_t mesg_length
= 0;
187 // Parse the incoming message for validity. The check needs to be
188 // performed by the messaging objects.
189 if (this->messaging_object ()->parse_next_message (qd
,
193 if (qd
.missing_data () == TAO_MISSING_DATA_UNDEFINED
)
195 // parse/marshal error happened
199 if (message_block
.length () > mesg_length
)
201 // we read too much data
205 if (message_block
.space () < qd
.missing_data ())
207 size_t const message_size
= message_block
.length ()
208 + qd
.missing_data ();
210 // reallocate buffer with correct size on heap
211 if (ACE_CDR::grow (&message_block
, message_size
) == -1)
213 if (TAO_debug_level
> 0)
215 TAOLIB_ERROR ((LM_ERROR
,
216 "TAO (%P|%t) - SHMIOP_Transport[%d]::handle_input, "
217 "error growing message buffer\n",
225 // As this used for transports where things are available in one
226 // shot this looping should not create any problems.
227 for (size_t n
= qd
.missing_data ();
233 // We would have liked to use something like a recv_n ()
234 // here. But at the time when the code was written, the MEM_Stream
235 // classes had poor support for recv_n (). Till a day when we
236 // get proper recv_n (), let us stick with this. The other
237 // argument that can be said against this is that, this is the
238 // bad layer in which this is being done ie. recv_n is
240 bytes
= this->recv (message_block
.wr_ptr (),
250 message_block
.wr_ptr (bytes
);
255 // Now we have a full message in our buffer. Just go ahead and
257 if (this->process_parsed_messages (&qd
, rh
) == -1)
267 TAO_SHMIOP_Transport::send_request (TAO_Stub
*stub
,
268 TAO_ORB_Core
*orb_core
,
269 TAO_OutputCDR
&stream
,
270 TAO_Message_Semantics message_semantics
,
271 ACE_Time_Value
*max_wait_time
)
273 if (this->ws_
->sending_request (orb_core
,
274 message_semantics
) == -1)
279 if (this->send_message (stream
,
283 max_wait_time
) == -1)
288 this->first_request_sent();
294 TAO_SHMIOP_Transport::send_message (TAO_OutputCDR
&stream
,
296 TAO_ServerRequest
*request
,
297 TAO_Message_Semantics message_semantics
,
298 ACE_Time_Value
*max_wait_time
)
300 // Format the message in the stream first
301 if (this->messaging_object ()->format_message (stream
, stub
, request
) != 0)
306 // Strictly speaking, should not need to loop here because the
307 // socket never gets set to a nonblocking mode ... some Linux
308 // versions seem to need it though. Leaving it costs little.
310 // This guarantees to send all data (bytes) or return an error.
311 ssize_t n
= this->send_message_shared (stub
,
319 TAOLIB_DEBUG ((LM_DEBUG
,
320 ACE_TEXT ("TAO (%P|%t) closing transport %d after fault %p\n"),
322 ACE_TEXT ("send_message ()\n")));
330 TAO_END_VERSIONED_NAMESPACE_DECL
332 #endif /* TAO_HAS_SHMIOP && TAO_HAS_SHMIOP != 0 */