diff options
Diffstat (limited to 'TAO/tao/IIOP_Transport.cpp')
-rw-r--r-- | TAO/tao/IIOP_Transport.cpp | 100 |
1 files changed, 93 insertions, 7 deletions
diff --git a/TAO/tao/IIOP_Transport.cpp b/TAO/tao/IIOP_Transport.cpp index fddb13520b5..e40e21738c5 100644 --- a/TAO/tao/IIOP_Transport.cpp +++ b/TAO/tao/IIOP_Transport.cpp @@ -13,6 +13,9 @@ #include "tao/ORB_Core.h" #include "tao/Thread_Lane_Resources.h" #include "tao/Transport_Mux_Strategy.h" +#include "tao/MMAP_Allocator.h" + +#include "ace/OS_NS_sys_sendfile.h" ACE_RCSID (tao, IIOP_Transport, @@ -71,8 +74,11 @@ TAO_IIOP_Transport::send (iovec *iov, int iovcnt, size_t &bytes_transferred, const ACE_Time_Value *max_wait_time) { - ssize_t retval = this->connection_handler_->peer ().sendv (iov, iovcnt, - max_wait_time); + ssize_t const retval = + this->connection_handler_->peer ().sendv (iov, + iovcnt, + max_wait_time); + if (retval > 0) bytes_transferred = retval; else @@ -89,14 +95,94 @@ TAO_IIOP_Transport::send (iovec *iov, int iovcnt, return retval; } +#ifdef ACE_HAS_SENDFILE +ssize_t +TAO_IIOP_Transport::sendfile (TAO_MMAP_Allocator * allocator, + iovec * iov, + int iovcnt, + size_t &bytes_transferred, + ACE_Time_Value const * timeout) +{ + // @@ We should probably set the TCP_CORK socket option to minimize + // network operations. It may also be useful to adjust the + // socket send buffer size accordingly. + + // If we don't have an allocator, fallback to the regular way of sending + // data + if (allocator == 0) + return this->send (iov, iovcnt, bytes_transferred, timeout); + + // We can only use sendfile when all data is coming from the mmap allocator, + // if not, we just fallback to to the regular way of sending data + iovec * const off_check_begin = iov; + iovec * const off_check_end = iov + iovcnt; + for (iovec * index = off_check_begin; index != off_check_end; ++index) + { + if (-1 == allocator->offset (index->iov_base)) + return this->send (iov, iovcnt, bytes_transferred, timeout); + } + + ssize_t retval = -1; + + ACE_HANDLE const in_fd = allocator->handle (); + + if (in_fd == ACE_INVALID_HANDLE) + return retval; + + ACE_HANDLE const out_fd = + this->connection_handler_->peer ().get_handle (); + + iovec * const begin = iov; + iovec * const end = iov + iovcnt; + for (iovec * i = begin; i != end; ++i) + { + off_t offset = allocator->offset (i->iov_base); + + if (timeout) + { + int val = 0; + if (ACE::enter_send_timedwait (out_fd, timeout, val) == -1) + return retval; + else + { + retval = + ACE_OS::sendfile (out_fd, in_fd, &offset, i->iov_len); + ACE::restore_non_blocking_mode (out_fd, val); + + } + } + else + { + retval = ACE_OS::sendfile (out_fd, in_fd, &offset, i->iov_len); + } + + if (retval <= 0) // Report errors below. + break; + + bytes_transferred += static_cast<size_t> (retval); + } + + if (retval <= 0 && TAO_debug_level > 4) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - IIOP_Transport[%d]::sendfile, ") + ACE_TEXT ("sendfile failure - %m (errno: %d)\n"), + this->id (), + errno)); + } + + return retval; +} +#endif /* ACE_HAS_SENDFILE */ + ssize_t TAO_IIOP_Transport::recv (char *buf, size_t len, const ACE_Time_Value *max_wait_time) { - ssize_t n = this->connection_handler_->peer ().recv (buf, - len, - max_wait_time); + ssize_t const n = this->connection_handler_->peer ().recv (buf, + len, + max_wait_time); // Do not print the error message if it is a timeout, which could // occur in thread-per-connection. @@ -166,7 +252,7 @@ TAO_IIOP_Transport::send_message (TAO_OutputCDR &stream, return -1; // This guarantees to send all data (bytes) or return an error. - const ssize_t n = this->send_message_shared (stub, + ssize_t const n = this->send_message_shared (stub, message_semantics, stream.begin (), max_wait_time); @@ -345,7 +431,7 @@ TAO_IIOP_Transport::get_listen_point ( iiop_acceptor->endpoints (); // Get the endpoint count - const size_t count = + size_t const count = iiop_acceptor->endpoint_count (); // Get the local address of the connection |