summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-12-07 03:35:51 +0000
committerirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-12-07 03:35:51 +0000
commitfbfd367ed60631f327fd6eccfa312230845c8fbf (patch)
tree822082ba0117438680286ce346b1d419758935a6
parent716e8019ac309fa3b47839d576ea7e3d18f16a2b (diff)
downloadATCD-fbfd367ed60631f327fd6eccfa312230845c8fbf.tar.gz
ChangeLogTag: Mon Dec 06 21:16:53 1999 Irfan Pyarali <irfan@cs.wustl.edu>
-rw-r--r--ChangeLog-99b95
-rw-r--r--TAO/ChangeLog-99c31
-rw-r--r--TAO/examples/Buffered_Oneways/client.cpp3
-rw-r--r--TAO/tao/IIOP_Connect.cpp8
-rw-r--r--TAO/tao/IIOP_Transport.cpp89
-rw-r--r--TAO/tao/IIOP_Transport.h8
-rw-r--r--TAO/tao/Pluggable.cpp123
-rw-r--r--TAO/tao/Pluggable.h20
-rw-r--r--TAO/tao/Sync_Strategies.cpp127
-rw-r--r--TAO/tao/Sync_Strategies.h14
-rw-r--r--TAO/tao/UIOP_Connect.cpp8
-rw-r--r--TAO/tao/UIOP_Transport.cpp89
-rw-r--r--TAO/tao/UIOP_Transport.h8
-rw-r--r--ace/ACE.cpp1940
-rw-r--r--ace/ACE.h422
-rw-r--r--ace/ACE.i58
-rw-r--r--ace/Handle_Set.h6
-rw-r--r--ace/Handle_Set.i37
-rw-r--r--ace/OS.cpp92
-rw-r--r--ace/OS.h53
-rw-r--r--ace/SOCK_Dgram.cpp150
-rw-r--r--ace/SOCK_Dgram.h13
-rw-r--r--ace/SOCK_IO.cpp6
-rw-r--r--ace/SOCK_IO.h113
-rw-r--r--ace/SOCK_IO.i142
-rw-r--r--ace/SOCK_Stream.h92
-rw-r--r--ace/SOCK_Stream.i112
-rw-r--r--ace/config-win32-common.h22
28 files changed, 2287 insertions, 1594 deletions
diff --git a/ChangeLog-99b b/ChangeLog-99b
index 907fdf84d29..97868106212 100644
--- a/ChangeLog-99b
+++ b/ChangeLog-99b
@@ -1,3 +1,98 @@
+Mon Dec 06 21:16:53 1999 Irfan Pyarali <irfan@cs.wustl.edu>
+
+ * ace/SOCK_Dgram.cpp (send): Added missing timed send.
+
+ * ace/SOCK_IO.h (ACE_SOCK_IO): Most methods now support an
+ optional timeout parameter.
+
+ * ace/SOCK_Stream.h (ACE_SOCK_Stream): All methods now support an
+ optional timeout parameter. Also fixed the <len> parameter type
+ in recv_urg and send_urg to be size_t instead of int.
+
+ * ace/ACE:
+
+ - All the I/O function were made consistent in ACE. This
+ included matching send and recv functions, all of which now
+ support timeouts.
+
+ - Many of the timed functions, e.g., ACE::readv() and
+ ACE::sendto(), were changed such that the <timeout == 0> case
+ was made common between the code that expected OS provided timed
+ functions and the other where the timed function was simulated
+ by ACE.
+
+ - Certain file I/O operation were made simple by removing the
+ extra <timeout> parameter. Timeouts are not supported in file
+ I/O. In some cases, e.g., the timed writev and readv functions,
+ the function was removed since it was not necessary as taking
+ the <timeout> parameter made it redundant with the function in
+ ACE_OS.
+
+ - The "_n" methods were given a performance boost when they are
+ used with timeouts. We only set the handle into non-blocking
+ mode only once rather than for every iteration in the loop.
+
+ - Added send/recv/send_n/recv/recv_n methods that take a message
+ block as the data container.
+
+ - Here is the description of the updated functions from the
+ documentation:
+ ________________________________________
+
+ The <timeout> parameter in the following methods indicates how
+ long to blocking trying to transfer data. If <timeout> == 0,
+ then the call behaves as a normal send/recv call, i.e., for
+ blocking sockets, the call will block until action is possible;
+ for non-blocking sockets, EWOULDBLOCK will be returned if no
+ action is immediately possible.
+
+ If <timeout> != 0, the call will wait until the relative time
+ specified in *<timeout> elapses.
+
+ Errors are reported by -1 and 0 return values. If the operation
+ times out, -1 is returned with <errno == ETIME>. If it succeeds
+ the number of bytes transferred is returned.
+
+ The "_n" I/O methods keep looping until all the data has been
+ transferred. These methods also work for sockets in
+ non-blocking mode i.e., they keep looping on EWOULDBLOCK.
+ <timeout> is used to make sure we keep making progress, i.e.,
+ the same timeout value is used for every I/O operation in the
+ loop and the timeout is not counted down. If the transfer times
+ out, the number of bytes transferred so far are returned.
+
+ Methods with <iovec> parameter are I/O vector variants of the
+ I/O operations.
+ ________________________________________
+
+ * ace/config-win32-common.h: Set IOV_MAX on Win32 to be 1024. It
+ seems like Win32 does not have a limit on the number of buffers
+ that can be transferred by the scatter/gather type of I/O
+ functions, e.g., WSASend and WSARecv. We are arbitrarily
+ setting this to be 1k for now. The typically use case is to
+ create an I/O vector array of size IOV_MAX on the stack and then
+ filled in. Note that we probably don't want too big a value for
+ IOV_MAX since it may mostly go to waste or the size of the
+ activation record may become excessively large.
+
+ * ace/OS:
+
+ The "faked" readv() in ACE for operating systems without it was
+ calling read_n(). This was changed to call read() since readv()
+ makes no guarantee that everything requested will be read. Same
+ changes applied for writev().
+
+ send_n() does not belong in the OS class. It belongs in the ACE
+ class. Therefore, it was moved.
+
+ read_n() is only called for file handles (and not for socket
+ handles). Therefore, there is no point in checking for
+ EWOULDBLOCK. Same change was made to write_n().
+
+ * ace/Handle_Set.h (ACE_Handle_Set): Added an explicit fdset()
+ function to get to the fd_set *. This eliminates the need for
+ the stupid cast operator.
+
Mon Dec 6 21:13:08 1999 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
* ace/Configuration.cpp (set_string_value): When setting a value
diff --git a/TAO/ChangeLog-99c b/TAO/ChangeLog-99c
index 2278968861d..f8db68e8ba0 100644
--- a/TAO/ChangeLog-99c
+++ b/TAO/ChangeLog-99c
@@ -1,6 +1,33 @@
+Mon Dec 06 21:16:53 1999 Irfan Pyarali <irfan@cs.wustl.edu>
+
+ * tao/IIOP_Transport.cpp (send/recv):
+ * tao/UIOP_Transport.cpp (send/recv):
+
+ - Changed to use the new timed I/O APIs in ACE.
+
+ - The <timeout> parameter was made const.
+
+ - Changed how the destructor handles buffered oneways.
+
+ * tao/UIOP_Connect.cpp (handle_timeout):
+ * tao/IIOP_Connect.cpp (handle_timeout):
+
+ Changed how timeouts handle buffered oneways.
+
+ * tao/Pluggable.cpp (send_buffered_messages): Some of the methods
+ were moved from the sync strategies to the transport class.
+ This makes them easier to use without the presence of the stub,
+ e.g., during the destruction of the transport and when timeouts
+ occur.
+
+ * examples/Buffered_Oneways/client.cpp (main): Initialized all the
+ fields of the <buffering_constraint> structure. This will
+ prevent UMRs from purify. Thanks to Jeff for pointing out the
+ source of the UMRs.
+
Mon Dec 6 13:16:21 1999 Balachandran Natarajan <bala@cs.wustl.edu>
- * tao/GIOP1_2.pidl (GIOP ):
+ * tao/GIOP1_2.pidl (GIOP ):
* tao/GIOPC.h:
* tao/GIOPC.cpp:
* tao/GIOPC.i: Some new data types that have been added to GIOP
@@ -8,7 +35,7 @@ Mon Dec 6 13:16:21 1999 Balachandran Natarajan <bala@cs.wustl.edu>
problem for the CORBA namespace.
* tao/Makefile: Added GIOPC.cpp to the list of files and also
- updated the dependencies.
+ updated the dependencies.
Sun Dec 5 14:43:42 1999 Carlos O'Ryan <coryan@cs.wustl.edu>
diff --git a/TAO/examples/Buffered_Oneways/client.cpp b/TAO/examples/Buffered_Oneways/client.cpp
index 2652e1cc529..4732037d4e0 100644
--- a/TAO/examples/Buffered_Oneways/client.cpp
+++ b/TAO/examples/Buffered_Oneways/client.cpp
@@ -163,6 +163,9 @@ main (int argc, char **argv)
// Start off with no constraints.
TAO::BufferingConstraint buffering_constraint;
+ buffering_constraint.message_count = 0;
+ buffering_constraint.message_bytes = 0;
+ buffering_constraint.timeout = 0;
buffering_constraint.mode = TAO::BUFFER_NONE;
// If valid <message_count>, set the implicit flushing to
diff --git a/TAO/tao/IIOP_Connect.cpp b/TAO/tao/IIOP_Connect.cpp
index dfae9b98595..bb3f62fe0ae 100644
--- a/TAO/tao/IIOP_Connect.cpp
+++ b/TAO/tao/IIOP_Connect.cpp
@@ -430,8 +430,12 @@ int
TAO_IIOP_Client_Connection_Handler::handle_timeout (const ACE_Time_Value &,
const void *)
{
- // Called when buffering timer expires.
- this->transport ()->flush_buffered_messages ();
+ //
+ // This method is called when buffering timer expires.
+ //
+
+ // Cannot deal with errors, and therefore they are ignored.
+ this->transport ()->send_buffered_messages ();
return 0;
}
diff --git a/TAO/tao/IIOP_Transport.cpp b/TAO/tao/IIOP_Transport.cpp
index 9471db6b05d..6727a930585 100644
--- a/TAO/tao/IIOP_Transport.cpp
+++ b/TAO/tao/IIOP_Transport.cpp
@@ -56,7 +56,12 @@ TAO_IIOP_Transport::TAO_IIOP_Transport (TAO_IIOP_Handler_Base *handler,
TAO_IIOP_Transport::~TAO_IIOP_Transport (void)
{
- this->flush_buffered_messages ();
+ // Cannot deal with errors, and therefore they are ignored.
+ this->send_buffered_messages ();
+
+ // Note that it also doesn't matter how much of the data was
+ // actually sent.
+ this->dequeue_all ();
}
TAO_IIOP_Handler_Base *&
@@ -307,7 +312,7 @@ TAO_IIOP_Client_Transport::register_handler (void)
ssize_t
TAO_IIOP_Transport::send (TAO_Stub *stub,
const ACE_Message_Block *message_block,
- ACE_Time_Value *max_wait_time)
+ const ACE_Time_Value *max_wait_time)
{
if (stub == 0)
{
@@ -327,93 +332,37 @@ TAO_IIOP_Transport::send (TAO_Stub *stub,
ssize_t
TAO_IIOP_Transport::send (const ACE_Message_Block *message_block,
- ACE_Time_Value *max_wait_time)
+ const ACE_Time_Value *max_wait_time)
{
TAO_FUNCTION_PP_TIMEPROBE (TAO_IIOP_TRANSPORT_SEND_START);
- // @@ This code should be refactored into ACE.cpp or something
- // similar!
-
- // For the most part this was copied from GIOP::send_request and
- // friends.
-
- iovec iov[IOV_MAX];
- int iovcnt = 0;
- ssize_t n = 0;
- ssize_t nbytes = 0;
-
- for (const ACE_Message_Block *i = message_block;
- i != 0;
- i = i->cont ())
- {
- // Make sure there is something to send!
- if (i->length () > 0)
- {
- iov[iovcnt].iov_base = i->rd_ptr ();
- iov[iovcnt].iov_len = i->length ();
- iovcnt++;
-
- // The buffer is full make a OS call. @@ TODO this should
- // be optimized on a per-platform basis, for instance, some
- // platforms do not implement writev() there we should copy
- // the data into a buffer and call send_n(). In other cases
- // there may be some limits on the size of the iovec, there
- // we should set IOV_MAX to that limit.
- if (iovcnt == IOV_MAX)
- {
- if (max_wait_time == 0)
- n = this->handler_->peer ().sendv_n (iov,
- iovcnt);
- else
- n = ACE::writev (this->handler_->peer ().get_handle (),
- iov,
- iovcnt,
- max_wait_time);
-
- if (n <= 0)
- return n;
-
- nbytes += n;
- iovcnt = 0;
- }
- }
- }
-
- // Check for remaining buffers to be sent!
- if (iovcnt != 0)
- {
- n = this->handler_->peer ().sendv_n (iov,
- iovcnt);
- if (n < 1)
- return n;
-
- nbytes += n;
- }
-
- return nbytes;
+ return ACE::send_n (this->handle (),
+ message_block,
+ max_wait_time);
}
ssize_t
TAO_IIOP_Transport::send (const u_char *buf,
size_t len,
- ACE_Time_Value *)
+ const ACE_Time_Value *max_wait_time)
{
TAO_FUNCTION_PP_TIMEPROBE (TAO_IIOP_TRANSPORT_SEND_START);
- return this->handler_->peer ().send_n (buf, len);
+ return this->handler_->peer ().send_n (buf,
+ len,
+ max_wait_time);
}
ssize_t
TAO_IIOP_Transport::recv (char *buf,
size_t len,
- ACE_Time_Value *max_wait_time)
+ const ACE_Time_Value *max_wait_time)
{
TAO_FUNCTION_PP_TIMEPROBE (TAO_IIOP_TRANSPORT_RECEIVE_START);
- return ACE::recv_n (this->handler_->peer ().get_handle (),
- buf,
- len,
- max_wait_time);
+ return this->handler_->peer ().recv_n (buf,
+ len,
+ max_wait_time);
}
// Default action to be taken for send request.
diff --git a/TAO/tao/IIOP_Transport.h b/TAO/tao/IIOP_Transport.h
index a82205a4717..90335ab8130 100644
--- a/TAO/tao/IIOP_Transport.h
+++ b/TAO/tao/IIOP_Transport.h
@@ -63,15 +63,15 @@ public:
virtual ACE_Event_Handler *event_handler (void);
virtual ssize_t send (TAO_Stub *stub,
const ACE_Message_Block *mblk,
- ACE_Time_Value *s = 0);
+ const ACE_Time_Value *s = 0);
virtual ssize_t send (const ACE_Message_Block *mblk,
- ACE_Time_Value *s = 0);
+ const ACE_Time_Value *s = 0);
virtual ssize_t send (const u_char *buf,
size_t len,
- ACE_Time_Value *s = 0);
+ const ACE_Time_Value *s = 0);
virtual ssize_t recv (char *buf,
size_t len,
- ACE_Time_Value *s = 0);
+ const ACE_Time_Value *s = 0);
virtual int send_request (TAO_Stub *stub,
TAO_ORB_Core *orb_core ,
TAO_OutputCDR &stream,
diff --git a/TAO/tao/Pluggable.cpp b/TAO/tao/Pluggable.cpp
index 612072bb6b7..aa875436e92 100644
--- a/TAO/tao/Pluggable.cpp
+++ b/TAO/tao/Pluggable.cpp
@@ -51,25 +51,126 @@ TAO_Transport::~TAO_Transport (void)
delete this->buffering_queue_;
}
+ssize_t
+TAO_Transport::send_buffered_messages (const ACE_Time_Value *max_wait_time)
+{
+ // Make sure we have a buffering queue and there are messages in it.
+ if (this->buffering_queue_ == 0 ||
+ this->buffering_queue_->is_empty ())
+ return 0;
+
+ // Get the first message from the queue.
+ ACE_Message_Block *queued_message = 0;
+ ssize_t result = this->buffering_queue_->peek_dequeue_head (queued_message);
+
+ // @@ What to do here on failures?
+ ACE_ASSERT (result != -1);
+
+ // Actual network send.
+ result = this->send (queued_message,
+ max_wait_time);
+
+ // Socket closed.
+ if (result == 0)
+ {
+ this->dequeue_all ();
+ return -1;
+ }
+
+ // Cannot send.
+ if (result == -1)
+ {
+ // Timeout.
+ if (errno == ETIME)
+ {
+ // Since we queue up the message, this is not an error. We
+ // can try next time around.
+ return 0;
+ }
+ // Non-timeout error.
+ else
+ {
+ this->dequeue_all ();
+ return -1;
+ }
+ }
+
+ // If successful in sending some or all of the data, reset the queue
+ // appropriately.
+ this->reset_queued_message (queued_message,
+ result);
+
+ // Indicate success.
+ return result;
+}
+
void
-TAO_Transport::flush_buffered_messages (void)
+TAO_Transport::dequeue_head (void)
{
- // If we have a buffering queue.
+ // Remove from the head of the queue.
+ ACE_Message_Block *message_block = 0;
+ int result = this->buffering_queue_->dequeue_head (message_block);
+
+ // @@ What to do here on failures?
+ ACE_ASSERT (result != -1);
+ ACE_UNUSED_ARG (result);
+
+ // Release the memory.
+ message_block->release ();
+}
+
+void
+TAO_Transport::dequeue_all (void)
+{
+ // Flush all queued messages.
if (this->buffering_queue_)
{
- // Flush all queued messages.
while (!this->buffering_queue_->is_empty ())
+ this->dequeue_head ();
+ }
+}
+
+void
+TAO_Transport::reset_queued_message (ACE_Message_Block *message_block,
+ size_t bytes_delivered)
+{
+ while (message_block != 0 &&
+ bytes_delivered != 0)
+ {
+ // Partial send.
+ if (message_block->length () > bytes_delivered)
{
- // Get the first message from the queue.
- ACE_Message_Block *queued_message = 0;
- this->buffering_queue_->dequeue_head (queued_message);
+ // Reset so that we skip this in the next send.
+ message_block->rd_ptr (bytes_delivered);
- // Actual network send. Cannot deal with errors, and
- // therefore they are ignored.
- this->send (queued_message);
+ // Hand adjust <message_length>.
+ this->buffering_queue_->message_length (this->buffering_queue_->message_length () - bytes_delivered);
+
+ break;
+ }
+
+ // <message_block> was completely sent.
+ bytes_delivered -= message_block->length ();
+
+ // Check continuation chain.
+ if (message_block->cont ())
+ {
+ // Reset so that we skip this message block in the next send.
+ message_block->rd_ptr (message_block->length ());
+
+ // Hand adjust <message_length>.
+ this->buffering_queue_->message_length (this->buffering_queue_->message_length () - bytes_delivered);
+
+ // Next selection.
+ message_block = message_block->cont ();
+ }
+ else
+ {
+ // Go to the next one.
+ message_block = message_block->next ();
- // Release the memory.
- queued_message->release ();
+ // Release this <message_block>.
+ this->dequeue_head ();
}
}
}
diff --git a/TAO/tao/Pluggable.h b/TAO/tao/Pluggable.h
index 2b8b386f670..2f3b601ecaa 100644
--- a/TAO/tao/Pluggable.h
+++ b/TAO/tao/Pluggable.h
@@ -84,9 +84,9 @@ public:
virtual ssize_t send (TAO_Stub *stub,
const ACE_Message_Block *mblk,
- ACE_Time_Value *s = 0) = 0;
+ const ACE_Time_Value *s = 0) = 0;
virtual ssize_t send (const ACE_Message_Block *mblk,
- ACE_Time_Value *s = 0) = 0;
+ const ACE_Time_Value *s = 0) = 0;
// Write the complete Message_Block chain to the connection.
// @@ The ACE_Time_Value *s is just a place holder for now. It is
// not clear this this is the best place to specify this. The actual
@@ -94,12 +94,12 @@ public:
virtual ssize_t send (const u_char *buf,
size_t len,
- ACE_Time_Value *s = 0) = 0;
+ const ACE_Time_Value *s = 0) = 0;
// Write the contents of the buffer of length len to the connection.
virtual ssize_t recv (char *buf,
size_t len,
- ACE_Time_Value *s = 0) = 0;
+ const ACE_Time_Value *s = 0) = 0;
// Read len bytes from into buf.
// @@ The ACE_Time_Value *s is just a place holder for now. It is
// not clear this this is the best place to specify this. The actual
@@ -178,10 +178,18 @@ public:
void buffering_timeout_value (const ACE_Time_Value &time);
// Timeout value associated with buffering.
- void flush_buffered_messages (void);
- // Flush any messages that have been buffered.
+ ssize_t send_buffered_messages (const ACE_Time_Value *max_wait_time = 0);
+ // Send any messages that have been buffered.
protected:
+
+ void dequeue_head (void);
+
+ void dequeue_all (void);
+
+ void reset_queued_message (ACE_Message_Block *message_block,
+ size_t bytes_delivered);
+
CORBA::ULong tag_;
// IOP protocol tag.
diff --git a/TAO/tao/Sync_Strategies.cpp b/TAO/tao/Sync_Strategies.cpp
index b1688e4abd3..5456dc10cef 100644
--- a/TAO/tao/Sync_Strategies.cpp
+++ b/TAO/tao/Sync_Strategies.cpp
@@ -19,7 +19,7 @@ ssize_t
TAO_Transport_Sync_Strategy::send (TAO_Transport &transport,
TAO_Stub &,
const ACE_Message_Block *message_block,
- ACE_Time_Value *max_wait_time)
+ const ACE_Time_Value *max_wait_time)
{
// Immediate delegation to the transport.
return transport.send (message_block,
@@ -32,7 +32,7 @@ ssize_t
TAO_None_Sync_Strategy::send (TAO_Transport &transport,
TAO_Stub &stub,
const ACE_Message_Block *message_block,
- ACE_Time_Value *max_wait_time)
+ const ACE_Time_Value *max_wait_time)
{
ssize_t result = 0;
@@ -61,131 +61,14 @@ TAO_None_Sync_Strategy::send (TAO_Transport &transport,
stub,
buffering_queue))
{
- // Copy the timeout value since we don't want to change it. The
- // caller will change appropriately.
- ACE_Time_Value timeout_value;
- ACE_Time_Value *timeout = 0;
- if (max_wait_time)
- {
- timeout_value = *max_wait_time;
- timeout = &timeout_value;
- }
-
- ACE_Countdown_Time countdown (timeout);
-
- // Flush all queued messages.
- while (!buffering_queue.is_empty ())
- {
- // Get the first message from the queue.
- ACE_Message_Block *queued_message = 0;
- result = buffering_queue.peek_dequeue_head (queued_message);
-
- // @@ What to do here on failures?
- ACE_ASSERT (result != -1);
-
- // Actual network send.
- result = transport.send (queued_message,
- timeout);
-
- // Socket closed.
- if (result == 0)
- {
- this->dequeue_all (buffering_queue);
- return -1;
- }
-
- // Cannot send.
- if (result == -1)
- {
- // Timeout.
- if (errno == ETIME)
- {
- // Since we queue up the message, this is not an
- // error. We can try next time around.
- return 0;
- }
- // Non-timeout error.
- else
- {
- this->dequeue_all (buffering_queue);
- return -1;
- }
- }
-
- ssize_t total_length = queued_message->total_length ();
-
- // If successful in sending the complete queued message.
- if (result == total_length)
- {
- this->dequeue_head (buffering_queue);
- countdown.update ();
- }
-
- // Partial send (re-adjust pointers without dequeuing the
- // message). This is not an error. We can try next time
- // around.
- else
- {
- this->reset_queued_message (buffering_queue,
- queued_message,
- result);
- return 0;
- }
- }
+ return transport.send_buffered_messages (max_wait_time);
}
- // I am hoping this return value is meaningful.
+ // Hoping that this return value is meaningful or at least
+ // acceptable.
return message_block->total_length ();
}
-void
-TAO_None_Sync_Strategy::dequeue_head (TAO_Transport_Buffering_Queue &buffering_queue)
-{
- ACE_Message_Block *message_block = 0;
-
- // Remove from the head of the queue.
- int result = buffering_queue.dequeue_head (message_block);
-
- // @@ What to do here on failures?
- ACE_ASSERT (result != -1);
- ACE_UNUSED_ARG (result);
-
- // Release the memory.
- message_block->release ();
-}
-
-void
-TAO_None_Sync_Strategy::dequeue_all (TAO_Transport_Buffering_Queue &buffering_queue)
-{
- // Flush all queued messages.
- while (!buffering_queue.is_empty ())
- this->dequeue_head (buffering_queue);
-}
-
-void
-TAO_None_Sync_Strategy::reset_queued_message (TAO_Transport_Buffering_Queue &buffering_queue,
- ACE_Message_Block *message_block,
- size_t bytes_delivered)
-{
- for (ACE_Message_Block *i = message_block;
- i != 0 && bytes_delivered != 0;
- i = i->cont ())
- {
- if (i->length () > bytes_delivered)
- {
- i->rd_ptr (bytes_delivered);
- bytes_delivered = 0;
- }
- else
- {
- bytes_delivered -= i->length ();
- i->rd_ptr (i->length ());
- }
- }
-
- buffering_queue.message_length (buffering_queue.message_length () - bytes_delivered);
-}
-
int
TAO_None_Sync_Strategy::buffering_constraints_reached (TAO_Transport &transport,
TAO_Stub &stub,
diff --git a/TAO/tao/Sync_Strategies.h b/TAO/tao/Sync_Strategies.h
index 35107737c73..b4cb70e0e4b 100644
--- a/TAO/tao/Sync_Strategies.h
+++ b/TAO/tao/Sync_Strategies.h
@@ -37,7 +37,7 @@ public:
virtual ssize_t send (TAO_Transport &transport,
TAO_Stub &stub,
const ACE_Message_Block *message_block,
- ACE_Time_Value *max_wait_time) = 0;
+ const ACE_Time_Value *max_wait_time) = 0;
};
class TAO_Export TAO_Transport_Sync_Strategy : public TAO_Sync_Strategy
@@ -46,7 +46,7 @@ public:
ssize_t send (TAO_Transport &transport,
TAO_Stub &stub,
const ACE_Message_Block *message_block,
- ACE_Time_Value *max_wait_time);
+ const ACE_Time_Value *max_wait_time);
};
#if defined (TAO_HAS_CORBA_MESSAGING)
@@ -57,7 +57,7 @@ public:
ssize_t send (TAO_Transport &transport,
TAO_Stub &stub,
const ACE_Message_Block *message_block,
- ACE_Time_Value *max_wait_time);
+ const ACE_Time_Value *max_wait_time);
virtual int buffering_constraints_reached (TAO_Transport &transport,
TAO_Stub &stub,
@@ -67,14 +67,6 @@ public:
const TAO::BufferingConstraint &buffering_constraint);
ACE_Time_Value time_conversion (const TimeBase::TimeT &time);
-
- void dequeue_head (TAO_Transport_Buffering_Queue &buffering_queue);
-
- void dequeue_all (TAO_Transport_Buffering_Queue &buffering_queue);
-
- void reset_queued_message (TAO_Transport_Buffering_Queue &buffering_queue,
- ACE_Message_Block *message_block,
- size_t bytes_delivered);
};
class TAO_Export TAO_Flush_Sync_Strategy : public TAO_None_Sync_Strategy
diff --git a/TAO/tao/UIOP_Connect.cpp b/TAO/tao/UIOP_Connect.cpp
index 73a4ff1e417..66bed11894a 100644
--- a/TAO/tao/UIOP_Connect.cpp
+++ b/TAO/tao/UIOP_Connect.cpp
@@ -397,8 +397,12 @@ int
TAO_UIOP_Client_Connection_Handler::handle_timeout (const ACE_Time_Value &,
const void *)
{
- // Called when buffering timer expires.
- this->transport ()->flush_buffered_messages ();
+ //
+ // This method is called when buffering timer expires.
+ //
+
+ // Cannot deal with errors, and therefore they are ignored.
+ this->transport ()->send_buffered_messages ();
return 0;
}
diff --git a/TAO/tao/UIOP_Transport.cpp b/TAO/tao/UIOP_Transport.cpp
index 64068097a3d..00404ef7df2 100644
--- a/TAO/tao/UIOP_Transport.cpp
+++ b/TAO/tao/UIOP_Transport.cpp
@@ -59,7 +59,12 @@ TAO_UIOP_Transport::TAO_UIOP_Transport (TAO_UIOP_Handler_Base *handler,
TAO_UIOP_Transport::~TAO_UIOP_Transport (void)
{
- this->flush_buffered_messages ();
+ // Cannot deal with errors, and therefore they are ignored.
+ this->send_buffered_messages ();
+
+ // Note that it also doesn't matter how much of the data was
+ // actually sent.
+ this->dequeue_all ();
}
TAO_UIOP_Handler_Base *&
@@ -311,7 +316,7 @@ TAO_UIOP_Client_Transport::register_handler (void)
ssize_t
TAO_UIOP_Transport::send (TAO_Stub *stub,
const ACE_Message_Block *message_block,
- ACE_Time_Value *max_wait_time)
+ const ACE_Time_Value *max_wait_time)
{
if (stub == 0)
{
@@ -331,93 +336,37 @@ TAO_UIOP_Transport::send (TAO_Stub *stub,
ssize_t
TAO_UIOP_Transport::send (const ACE_Message_Block *mblk,
- ACE_Time_Value *max_time_wait)
+ const ACE_Time_Value *max_time_wait)
{
TAO_FUNCTION_PP_TIMEPROBE (TAO_UIOP_TRANSPORT_SEND_START);
- // @@ This code should be refactored into ACE.cpp or something
- // similar!
-
- // For the most part this was copied from GIOP::send_request and
- // friends.
-
- iovec iov[IOV_MAX];
- int iovcnt = 0;
- ssize_t n = 0;
- ssize_t nbytes = 0;
-
- for (const ACE_Message_Block *i = mblk;
- i != 0;
- i = i->cont ())
- {
- // Make sure there is something to send!
- if (i->length () > 0)
- {
- iov[iovcnt].iov_base = i->rd_ptr ();
- iov[iovcnt].iov_len = i->length ();
- iovcnt++;
-
- // The buffer is full make a OS call. @@ TODO this should
- // be optimized on a per-platform basis, for instance, some
- // platforms do not implement writev() there we should copy
- // the data into a buffer and call send_n(). In other cases
- // there may be some limits on the size of the iovec, there
- // we should set IOV_MAX to that limit.
- if (iovcnt == IOV_MAX)
- {
- if (max_time_wait == 0)
- n = this->handler_->peer ().sendv_n (iov,
- iovcnt);
- else
- n = ACE::writev (this->handler_->peer ().get_handle (),
- iov,
- iovcnt,
- max_time_wait);
-
- if (n <= 0)
- return n;
-
- nbytes += n;
- iovcnt = 0;
- }
- }
- }
-
- // Check for remaining buffers to be sent!
- if (iovcnt != 0)
- {
- n = this->handler_->peer ().sendv_n (iov,
- iovcnt);
- if (n < 1)
- return n;
-
- nbytes += n;
- }
-
- return nbytes;
+ return ACE::send_n (this->handle (),
+ message_block,
+ max_wait_time);
}
ssize_t
TAO_UIOP_Transport::send (const u_char *buf,
size_t len,
- ACE_Time_Value *)
+ const ACE_Time_Value *max_wait_time)
{
TAO_FUNCTION_PP_TIMEPROBE (TAO_UIOP_TRANSPORT_SEND_START);
- return this->handler_->peer ().send_n (buf, len);
+ return this->handler_->peer ().send_n (buf,
+ len,
+ max_wait_time);
}
ssize_t
TAO_UIOP_Transport::recv (char *buf,
size_t len,
- ACE_Time_Value *max_wait_time)
+ const ACE_Time_Value *max_wait_time)
{
TAO_FUNCTION_PP_TIMEPROBE (TAO_UIOP_TRANSPORT_RECEIVE_START);
- return ACE::recv_n (this->handler_->peer ().get_handle (),
- buf,
- len,
- max_wait_time);
+ return this->handler_->peer ().recv_n (buf,
+ len,
+ max_wait_time);
}
// Default action to be taken for send request.
diff --git a/TAO/tao/UIOP_Transport.h b/TAO/tao/UIOP_Transport.h
index d73779f74e3..481e6232e6a 100644
--- a/TAO/tao/UIOP_Transport.h
+++ b/TAO/tao/UIOP_Transport.h
@@ -66,15 +66,15 @@ public:
virtual ACE_Event_Handler *event_handler (void);
virtual ssize_t send (TAO_Stub *stub,
const ACE_Message_Block *mblk,
- ACE_Time_Value *s = 0);
+ const ACE_Time_Value *s = 0);
virtual ssize_t send (const ACE_Message_Block *mblk,
- ACE_Time_Value *s = 0);
+ const ACE_Time_Value *s = 0);
virtual ssize_t send (const u_char *buf,
size_t len,
- ACE_Time_Value *s = 0);
+ const ACE_Time_Value *s = 0);
virtual ssize_t recv (char *buf,
size_t len,
- ACE_Time_Value *s = 0);
+ const ACE_Time_Value *s = 0);
virtual int send_request (TAO_Stub *stub,
TAO_ORB_Core *orb_core ,
TAO_OutputCDR &stream,
diff --git a/ace/ACE.cpp b/ace/ACE.cpp
index 9c2b9a46dbb..d4dabdb72b0 100644
--- a/ace/ACE.cpp
+++ b/ace/ACE.cpp
@@ -8,6 +8,7 @@
#include "ace/Object_Manager.h"
#include "ace/SString.h"
#include "ace/Version.h"
+#include "ace/Message_Block.h"
#if defined (ACE_LACKS_INLINE_FUNCTIONS)
#include "ace/ACE.i"
@@ -1066,41 +1067,339 @@ ACE::basename (const wchar_t *pathname, wchar_t delim)
}
#endif /* ACE_HAS_UNICODE */
-// Send N char *ptrs and int lengths. Note that the char *'s precede
-// the ints (basically, an varargs version of writev). The count N is
-// the *total* number of trailing arguments, *not* a couple of the
-// number of tuple pairs!
+ssize_t
+ACE::recv (ACE_HANDLE handle,
+ void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout)
+{
+ if (timeout == 0)
+ return ACE_OS::recv (handle, (char *) buf, len, flags);
+ else
+ {
+#if defined (ACE_HAS_RECV_TIMEDWAIT)
+ ACE_Time_Value copy = *timeout;
+ copy += ACE_OS::gettimeofday ();
+ timespec_t ts = copy;
+ return ::recv_timedwait (handle, buf, len, flags, &ts);
+#else
+ int val = 0;
+ if (ACE::enter_recv_timedwait (handle, timeout, val) ==-1)
+ return -1;
+ else
+ {
+ ssize_t bytes_transferred = ACE_OS::recv (handle, (char *) buf, len, flags);
+ ACE::restore_non_blocking_mode (handle, val);
+ return bytes_transferred;
+ }
+#endif /* ACE_HAS_RECV_TIMEDWAIT */
+ }
+}
ssize_t
-ACE::send (ACE_HANDLE handle, size_t n, ...)
+ACE::recv (ACE_HANDLE handle,
+ void *buf,
+ size_t n,
+ const ACE_Time_Value *timeout)
{
- ACE_TRACE ("ACE_SOCK_IO::send");
+ if (timeout == 0)
+ return ACE::recv_i (handle, buf, n);
+ else
+ {
+#if defined (ACE_HAS_READ_TIMEDWAIT)
+ ACE_Time_Value copy = *timeout;
+ copy += ACE_OS::gettimeofday ();
+ timespec_t ts = copy;
+ return ::read_timedwait (handle, buf, n, &ts);
+#else
+ int val = 0;
+ if (ACE::enter_recv_timedwait (handle, timeout, val) == -1)
+ return -1;
+ else
+ {
+ ssize_t bytes_transferred = ACE::recv_i (handle, buf, n);
+ ACE::restore_non_blocking_mode (handle, val);
+ return bytes_transferred;
+ }
+#endif /* ACE_HAS_READ_TIMEDWAIT */
+ }
+}
- va_list argp;
- size_t total_tuples = n / 2;
- iovec *iovp;
-#if defined (ACE_HAS_ALLOCA)
- iovp = (iovec *) alloca (total_tuples * sizeof (iovec));
+ssize_t
+ACE::recvmsg (ACE_HANDLE handle,
+ struct msghdr *msg,
+ int flags,
+ const ACE_Time_Value *timeout)
+{
+ if (timeout == 0)
+ return ACE_OS::recvmsg (handle, msg, flags);
+ else
+ {
+#if defined (ACE_HAS_RECVMSG_TIMEDWAIT)
+ ACE_Time_Value copy = *timeout;
+ copy += ACE_OS::gettimeofday ();
+ timespec_t ts = copy;
+ return ::recvmsg_timedwait (handle, msg, flags, &ts);
#else
- ACE_NEW_RETURN (iovp,
- iovec[total_tuples],
- -1);
-#endif /* !defined (ACE_HAS_ALLOCA) */
+ int val = 0;
+ if (ACE::enter_recv_timedwait (handle, timeout, val) == -1)
+ return -1;
+ else
+ {
+ int bytes_transferred = ACE_OS::recvmsg (handle, msg, flags);
+ ACE::restore_non_blocking_mode (handle, val);
+ return bytes_transferred;
+ }
+#endif /* ACE_HAS_RECVMSG_TIMEDWAIT */
+ }
+}
- va_start (argp, n);
+ssize_t
+ACE::recvfrom (ACE_HANDLE handle,
+ char *buf,
+ int len,
+ int flags,
+ struct sockaddr *addr,
+ int *addrlen,
+ const ACE_Time_Value *timeout)
+{
+ if (timeout == 0)
+ return ACE_OS::recvfrom (handle, buf, len, flags, addr, addrlen);
+ else
+ {
+#if defined (ACE_HAS_RECVFROM_TIMEDWAIT)
+ ACE_Time_Value copy = *timeout;
+ copy += ACE_OS::gettimeofday ();
+ timespec_t ts = copy;
+ return ::recvfrom_timedwait (handle, buf, len, flags, addr, addrlen, &ts);
+#else
+ int val = 0;
+ if (ACE::enter_recv_timedwait (handle, timeout, val) == -1)
+ return -1;
+ else
+ {
+ int bytes_transferred = ACE_OS::recvfrom (handle, buf, len, flags, addr, addrlen);
+ ACE::restore_non_blocking_mode (handle, val);
+ return bytes_transferred;
+ }
+#endif /* ACE_HAS_RECVFROM_TIMEDWAIT */
+ }
+}
- for (size_t i = 0; i < total_tuples; i++)
+ssize_t
+ACE::recv_n (ACE_HANDLE handle,
+ void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout)
+{
+ if (timeout == 0)
+ return ACE::recv_n_i (handle,
+ buf,
+ len,
+ flags);
+ else
+ return ACE::recv_n_i (handle,
+ buf,
+ len,
+ flags,
+ timeout);
+}
+
+ssize_t
+ACE::recv_n_i (ACE_HANDLE handle,
+ void *buf,
+ size_t len,
+ int flags)
+{
+ size_t bytes_transferred;
+ ssize_t n;
+
+ for (bytes_transferred = 0;
+ bytes_transferred < len;
+ bytes_transferred += n)
{
- iovp[i].iov_base = va_arg (argp, char *);
- iovp[i].iov_len = va_arg (argp, ssize_t);
+ n = ACE_OS::recv (handle,
+ (char *) buf + bytes_transferred,
+ len - bytes_transferred,
+ flags);
+ if (n == -1)
+ {
+ // If blocked, try again.
+ if (errno == EWOULDBLOCK)
+ n = 0;
+
+ //
+ // No timeouts in this version.
+ //
+
+ // Other errors.
+ return -1;
+ }
+ else if (n == 0)
+ return 0;
}
- ssize_t result = ACE_OS::sendv (handle, iovp, total_tuples);
-#if !defined (ACE_HAS_ALLOCA)
- delete [] iovp;
-#endif /* !defined (ACE_HAS_ALLOCA) */
- va_end (argp);
- return result;
+ return bytes_transferred;
+}
+
+ssize_t
+ACE::recv_n_i (ACE_HANDLE handle,
+ void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout)
+{
+ int val = 0;
+ ACE::record_and_set_non_blocking_mode (handle, val);
+
+ size_t bytes_transferred;
+ ssize_t n;
+ int error = 0;
+
+ for (bytes_transferred = 0;
+ bytes_transferred < len;
+ bytes_transferred += n)
+ {
+ int result = ACE::handle_read_ready (handle,
+ timeout);
+
+ if (result == -1)
+ {
+ // Timed out; return bytes transferred.
+ if (errno == ETIME)
+ break;
+
+ // Other errors.
+ error = 1;
+ break;
+ }
+
+ n = ACE_OS::recv (handle,
+ (char *) buf + bytes_transferred,
+ len - bytes_transferred,
+ flags);
+
+ // Errors (note that errno cannot be EWOULDBLOCK since select()
+ // just told us that data is available to read).
+ if (n == -1 || n == 0)
+ {
+ error = 1;
+ break;
+ }
+ }
+
+ ACE::restore_non_blocking_mode (handle, val);
+
+ if (error)
+ return -1;
+ else
+ return bytes_transferred;
+}
+
+ssize_t
+ACE::recv_n (ACE_HANDLE handle,
+ void *buf,
+ size_t len,
+ const ACE_Time_Value *timeout)
+{
+ if (timeout == 0)
+ return ACE::recv_n_i (handle,
+ buf,
+ len);
+ else
+ return ACE::recv_n_i (handle,
+ buf,
+ len,
+ timeout);
+}
+
+ssize_t
+ACE::recv_n_i (ACE_HANDLE handle,
+ void *buf,
+ size_t len)
+{
+ size_t bytes_transferred;
+ ssize_t n;
+
+ for (bytes_transferred = 0;
+ bytes_transferred < len;
+ bytes_transferred += n)
+ {
+ n = ACE::recv_i (handle,
+ (char *) buf + bytes_transferred,
+ len - bytes_transferred);
+ if (n == -1)
+ {
+ // If blocked, try again.
+ if (errno == EWOULDBLOCK)
+ n = 0;
+
+ //
+ // No timeouts in this version.
+ //
+
+ // Other errors.
+ return -1;
+ }
+ else if (n == 0)
+ return 0;
+ }
+
+ return bytes_transferred;
+}
+
+ssize_t
+ACE::recv_n_i (ACE_HANDLE handle,
+ void *buf,
+ size_t len,
+ const ACE_Time_Value *timeout)
+{
+ int val = 0;
+ ACE::record_and_set_non_blocking_mode (handle, val);
+
+ size_t bytes_transferred;
+ ssize_t n;
+ int error = 0;
+
+ for (bytes_transferred = 0;
+ bytes_transferred < len;
+ bytes_transferred += n)
+ {
+ int result = ACE::handle_read_ready (handle,
+ timeout);
+
+ if (result == -1)
+ {
+ // Timed out; return bytes transferred.
+ if (errno == ETIME)
+ break;
+
+ // Other errors.
+ error = 1;
+ break;
+ }
+
+ n = ACE::recv_i (handle,
+ (char *) buf + bytes_transferred,
+ len - bytes_transferred);
+
+ // Errors (note that errno cannot be EWOULDBLOCK since select()
+ // just told us that data is available to read).
+ if (n == -1 || n == 0)
+ {
+ error = 1;
+ break;
+ }
+ }
+
+ ACE::restore_non_blocking_mode (handle, val);
+
+ if (error)
+ return -1;
+ else
+ return bytes_transferred;
}
// This is basically an interface to ACE_OS::readv, that doesn't use
@@ -1112,8 +1411,6 @@ ACE::send (ACE_HANDLE handle, size_t n, ...)
ssize_t
ACE::recv (ACE_HANDLE handle, size_t n, ...)
{
- ACE_TRACE ("ACE_SOCK_IO::recv");
-
va_list argp;
size_t total_tuples = n / 2;
iovec *iovp;
@@ -1141,239 +1438,368 @@ ACE::recv (ACE_HANDLE handle, size_t n, ...)
return result;
}
-// Miscellaneous static methods used throughout ACE.
-
ssize_t
-ACE::send_n (ACE_HANDLE handle,
- const void *buf,
- size_t len,
- int flags)
+ACE::recvv (ACE_HANDLE handle,
+ iovec *iov,
+ int iovcnt,
+ const ACE_Time_Value *timeout)
{
- ACE_TRACE ("ACE::send_n");
- size_t bytes_written;
- ssize_t n;
-
- for (bytes_written = 0; bytes_written < len; bytes_written += n)
+ if (timeout == 0)
+ return ACE_OS::recvv (handle, iov, iovcnt);
+ else
{
- n = ACE_OS::send (handle,
- (const char *) buf + bytes_written,
- len - bytes_written,
- flags);
- if (n == -1)
+#if defined (ACE_HAS_READV_TIMEDWAIT)
+ ACE_Time_Value copy = *timeout;
+ copy += ACE_OS::gettimeofday ();
+ timespec_t ts = copy;
+ return ::readv_timedwait (handle, iov, iovcnt, &ts);
+#else
+ int val = 0;
+ if (ACE::enter_recv_timedwait (handle, timeout, val) == -1)
+ return -1;
+ else
{
- if (errno == EWOULDBLOCK)
- n = 0; // Keep trying to send.
- else
- return -1;
+ ssize_t bytes_transferred = ACE_OS::recvv (handle, iov, iovcnt);
+ ACE::restore_non_blocking_mode (handle, val);
+ return bytes_transferred;
}
+#endif /* ACE_HAS_READV_TIMEDWAIT */
}
+}
- return bytes_written;
+ssize_t
+ACE::recvv_n (ACE_HANDLE handle,
+ iovec *iov,
+ int iovcnt,
+ const ACE_Time_Value *timeout)
+{
+ if (timeout == 0)
+ return ACE::recvv_n_i (handle,
+ iov,
+ iovcnt);
+ else
+ return ACE::recvv_n_i (handle,
+ iov,
+ iovcnt,
+ timeout);
}
ssize_t
-ACE::recv_n (ACE_HANDLE handle, void *buf, size_t len)
+ACE::recvv_n_i (ACE_HANDLE handle,
+ iovec *iov,
+ int iovcnt)
{
- ACE_TRACE ("ACE::recv_n");
- size_t bytes_read;
- ssize_t n;
+ ssize_t bytes_transferred = 0;
- for (bytes_read = 0; bytes_read < len; bytes_read += n)
+ for (int s = 0;
+ s < iovcnt;
+ )
{
- n = ACE::recv (handle,
- (char *) buf + bytes_read,
- len - bytes_read);
+ ssize_t n = ACE_OS::recvv (handle,
+ iov + s,
+ iovcnt - s);
if (n == -1)
{
+ // If blocked, try again.
if (errno == EWOULDBLOCK)
- n = 0; // Keep trying to read.
- else
- return -1;
+ n = 0;
+
+ //
+ // No timeouts in this version.
+ //
+
+ // Other errors.
+ return -1;
}
else if (n == 0)
- break;
+ return 0;
+
+ for (bytes_transferred += n;
+ s < iovcnt
+ && n >= ACE_static_cast (ssize_t,
+ iov[s].iov_len);
+ s++)
+ n -= iov[s].iov_len;
+
+ if (n != 0)
+ {
+ char *base = ACE_reinterpret_cast (char *,
+ iov[s].iov_base);
+ iov[s].iov_base = base + n;
+ iov[s].iov_len = iov[s].iov_len - n;
+ }
}
- return bytes_read;
+ return bytes_transferred;
}
ssize_t
-ACE::recv_n (ACE_HANDLE handle, void *buf, size_t len, int flags)
+ACE::recvv_n_i (ACE_HANDLE handle,
+ iovec *iov,
+ int iovcnt,
+ const ACE_Time_Value *timeout)
{
- ACE_TRACE ("ACE::recv_n");
- size_t bytes_read;
- ssize_t n;
+ int val = 0;
+ ACE::record_and_set_non_blocking_mode (handle, val);
- for (bytes_read = 0; bytes_read < len; bytes_read += n)
+ ssize_t bytes_transferred = 0;
+ int error = 0;
+
+ for (int s = 0;
+ s < iovcnt;
+ )
{
- n = ACE::recv (handle,
- (char *) buf + bytes_read,
- len - bytes_read,
- flags);
+ int result = ACE::handle_read_ready (handle,
+ timeout);
- if (n == -1)
+ if (result == -1)
{
- if (errno == EWOULDBLOCK)
- n = 0; // Keep trying to read.
- else
- return -1;
- }
- else if (n == 0)
- break;
- }
+ // Timed out; return bytes transferred.
+ if (errno == ETIME)
+ break;
- return bytes_read;
-}
-
-int
-ACE::enter_recv_timedwait (ACE_HANDLE handle,
- const ACE_Time_Value *timeout,
- int &val)
-{
- // Give value a default value to keep Purify happy!
- val = 0;
+ // Other errors.
+ error = 1;
+ break;
+ }
- if (timeout == 0)
- return 0;
+ ssize_t n = ACE_OS::recvv (handle,
+ iov + s,
+ iovcnt - s);
-#if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)
+ // Errors (note that errno cannot be EWOULDBLOCK since select()
+ // just told us that data is available to read).
+ if (n == -1 || n == 0)
+ {
+ error = 1;
+ break;
+ }
- struct pollfd fds;
+ for (bytes_transferred += n;
+ s < iovcnt
+ && n >= ACE_static_cast (ssize_t,
+ iov[s].iov_len);
+ s++)
+ n -= iov[s].iov_len;
- fds.fd = handle;
- fds.events = POLLIN;
- fds.revents = 0;
-
- int a = ACE_OS::poll (&fds, 1, *timeout);
+ if (n != 0)
+ {
+ char *base = ACE_reinterpret_cast (char *,
+ iov[s].iov_base);
+ iov[s].iov_base = base + n;
+ iov[s].iov_len = iov[s].iov_len - n;
+ }
+ }
-#else
- ACE_Handle_Set handle_set;
- handle_set.set_bit (handle);
+ ACE::restore_non_blocking_mode (handle, val);
- // Wait for input to arrive or for the timeout to elapse.
- int a = ACE_OS::select (int (handle) + 1,
- (fd_set *) handle_set, // read_fds.
- (fd_set *) 0, // write_fds.
- (fd_set *) 0, // exception_fds.
- timeout);
-#endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */
+ if (error)
+ return -1;
+ else
+ return bytes_transferred;
+}
- switch ( a )
- {
- case 0: // Timer expired. return -1
- errno = ETIME;
- /* FALLTHRU */
- case -1: // we got here directly - select() returned -1.
- return -1;
- case 1: // OK to read now.
- /* FALLTHRU */
- default: // default is case a > 0; return a
- // really should assert if a != 1
- //assert( a == 1 );
- // We need to record whether we are already *in* nonblocking
- // mode, so that we can correctly reset the state when we're
- // done.
- val = ACE::get_flags (handle);
-
- if (ACE_BIT_DISABLED (val, ACE_NONBLOCK))
- // Set the handle into non-blocking mode if it's not
- // already in it.
- ACE::set_flags (handle, ACE_NONBLOCK);
- return a;
- }
+ssize_t
+ACE::recv (ACE_HANDLE handle,
+ ACE_Message_Block *message_block,
+ const ACE_Time_Value *timeout)
+{
+ return ACE::recv_i (handle,
+ message_block,
+ timeout,
+ 0);
}
-void
-ACE::leave_recv_timedwait (ACE_HANDLE handle,
- const ACE_Time_Value *timeout,
- int val)
+ssize_t
+ACE::recv_n (ACE_HANDLE handle,
+ ACE_Message_Block *message_block,
+ const ACE_Time_Value *timeout)
{
- if (timeout != 0
- && ACE_BIT_DISABLED (val,
- ACE_NONBLOCK))
- {
- // Save/restore errno.
- ACE_Errno_Guard error (errno);
- // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
- // originally.
- ACE::clr_flags (handle, ACE_NONBLOCK);
- }
+ return ACE::recv_i (handle,
+ message_block,
+ timeout,
+ 1);
}
-int
-ACE::enter_send_timedwait (ACE_HANDLE handle,
- const ACE_Time_Value* timeout,
- int &val)
+ssize_t
+ACE::recv_i (ACE_HANDLE handle,
+ ACE_Message_Block *message_block,
+ const ACE_Time_Value *timeout,
+ int loop)
{
- // Give value a default value to keep Purify happy!
- val = 0;
+ iovec iov[IOV_MAX];
+ int iovcnt = 0;
+ ssize_t n = 0;
+ ssize_t nbytes = 0;
+ ssize_t recv_size = 0;
- if (timeout==0)
- return 0;
+ while (message_block != 0)
+ {
+ // Check if this block has any space for incoming data.
+ if (message_block->length () > 0)
+ {
+ // Collect the data in the iovec.
+ iov[iovcnt].iov_base = message_block->rd_ptr ();
+ iov[iovcnt].iov_len = message_block->length ();
-#if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)
+ // Increment iovec counter.
+ iovcnt++;
- struct pollfd fds;
+ // Keep track of the number of bytes for this recv.
+ recv_size += message_block->length ();
- fds.fd = handle;
- fds.events = POLLOUT;
- fds.revents = 0;
+ // The buffer is full make a OS call. @@ TODO find a way to
+ // find IOV_MAX for platforms that do not define it rather
+ // than simply setting IOV_MAX to some arbitrary value such
+ // as 16.
+ if (iovcnt == IOV_MAX)
+ {
+ if (loop)
+ n = ACE::recvv_n (handle,
+ iov,
+ iovcnt,
+ timeout);
+ else
+ n = ACE::recvv (handle,
+ iov,
+ iovcnt,
+ timeout);
+
+ // Errors.
+ if (n <= 0)
+ return n;
+
+ // Success. Add to total bytes transferred.
+ nbytes += n;
+
+ // Reset iovec counter.
+ iovcnt = 0;
+
+ // If we sent everything we had accumulated in the last
+ // call, then keep going. If it was a partial recv, we
+ // won't continue.
+ if (recv_size == n)
+ recv_size = 0;
+ else
+ break;
+ }
+ }
- int a = ACE_OS::poll (&fds, 1, *timeout);
+ // Selection of the next message block: first check the
+ // continuation chain; then look at the next message block in
+ // the queue.
+ if (message_block->cont ())
+ message_block = message_block->cont ();
+ else
+ message_block = message_block->next ();
+ }
-#else
- ACE_Handle_Set handle_set;
- handle_set.set_bit (handle);
+ // Check for remaining buffers to be sent. This will happen when
+ // IOV_MAX is not a multiple of the number of message blocks.
+ if (iovcnt != 0)
+ {
+ n = ACE::recvv (handle,
+ iov,
+ iovcnt,
+ timeout);
- // On timed writes we always go into select(); only if the
- // handle is available for writing within the specified amount
- // of time do we put it in non-blocking mode
+ // Errors.
+ if (n <= 0)
+ return n;
- int a = ACE_OS::select (int (handle) + 1,
- (fd_set *) 0,
- (fd_set *) handle_set,
- (fd_set *) 0,
- timeout);
-#endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */
+ // Success. Add to total bytes transferred.
+ nbytes += n;
+ }
- switch ( a )
- {
- case 0: // Timer expired.
- errno = ETIME;
- /* FALLTHRU */
- case -1: // we got here directly - select() returned -1.
- return -1;
- case 1: // Ok to write now.
- /* FALLTHRU */
- default: // default is case a > 0; return a
- // really should assert if a != 1
- //assert( a == 1 );
- // We need to record whether we are already *in* nonblocking
- // mode, so that we can correctly reset the state when we're
- // done.
- val = ACE::get_flags (handle);
+ // Return total bytes transferred.
+ return nbytes;
+}
- if (ACE_BIT_DISABLED (val, ACE_NONBLOCK))
- // Set the handle into non-blocking mode if it's not
- // already in it.
- ACE::set_flags (handle, ACE_NONBLOCK);
- return a;
+ssize_t
+ACE::send (ACE_HANDLE handle,
+ const void *buf,
+ size_t n,
+ int flags,
+ const ACE_Time_Value *timeout)
+{
+ if (timeout == 0)
+ return ACE_OS::send (handle, (const char *) buf, n, flags);
+ else
+ {
+#if defined (ACE_HAS_SEND_TIMEDWAIT)
+ ACE_Time_Value copy = *timeout;
+ copy += ACE_OS::gettimeofday();
+ timespec_t ts = copy;
+ return ::send_timedwait (handle, buf, n, flags, &ts);
+#else
+ int val = 0;
+ if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
+ return -1;
+ else
+ {
+ ssize_t bytes_transferred = ACE_OS::send (handle, (const char *) buf, n, flags);
+ ACE::restore_non_blocking_mode (handle, val);
+ return bytes_transferred;
+ }
+#endif /* ACE_HAS_SEND_TIMEDWAIT */
}
}
-void
-ACE::leave_send_timedwait (ACE_HANDLE handle,
- const ACE_Time_Value *timeout,
- int val)
+ssize_t
+ACE::send (ACE_HANDLE handle,
+ const void *buf,
+ size_t n,
+ const ACE_Time_Value *timeout)
{
- if (timeout != 0
- && ACE_BIT_DISABLED (val, ACE_NONBLOCK))
+ if (timeout == 0)
+ return ACE::send_i (handle, buf, n);
+ else
{
- // Save/restore errno.
- ACE_Errno_Guard error (errno);
- // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
- // originally.
- ACE::clr_flags (handle, ACE_NONBLOCK);
+#if defined (ACE_HAS_WRITE_TIMEDWAIT)
+ ACE_Time_Value copy = *timeout;
+ copy += ACE_OS::gettimeofday ();
+ timespec_t ts = copy;
+ return ::write_timedwait (handle, buf, n, &ts);
+#else
+ int val = 0;
+ if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
+ return -1;
+ else
+ {
+ ssize_t bytes_transferred = ACE::send_i (handle, buf, n);
+ ACE::restore_non_blocking_mode (handle, val);
+ return bytes_transferred;
+ }
+#endif /* ACE_HAS_WRITE_TIMEDWAIT */
+ }
+}
+
+ssize_t
+ACE::sendmsg (ACE_HANDLE handle,
+ const struct msghdr *msg,
+ int flags,
+ const ACE_Time_Value *timeout)
+{
+ if (timeout == 0)
+ return ACE_OS::sendmsg (handle, msg, flags);
+ else
+ {
+#if defined (ACE_HAS_SENDMSG_TIMEDWAIT)
+ ACE_Time_Value copy = *timeout;
+ copy += ACE_OS::gettimeofday ();
+ timespec_t ts = copy;
+ return ::sendmsg_timedwait (handle, msg, flags, &ts);
+#else
+ int val = 0;
+ if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
+ return -1;
+ else
+ {
+ int bytes_transferred = ACE_OS::sendmsg (handle, msg, flags);
+ ACE::restore_non_blocking_mode (handle, val);
+ return bytes_transferred;
+ }
+#endif /* ACE_HAS_SENDMSG_TIMEDWAIT */
}
}
@@ -1386,207 +1812,744 @@ ACE::sendto (ACE_HANDLE handle,
int addrlen,
const ACE_Time_Value *timeout)
{
- // ACE_TRACE ("ACE::sendto");
-#if defined (ACE_HAS_SENDTO_TIMEDWAIT)
if (timeout == 0)
- return ACE_OS::sendto (handle, buf, len, flags, addr, addrlen);
+ return ACE_OS::sendto (handle, buf, len, flags, addr, addrlen);
else
{
+#if defined (ACE_HAS_SENDTO_TIMEDWAIT)
ACE_Time_Value copy = *timeout;
copy += ACE_OS::gettimeofday ();
timespec_t ts = copy;
- return ::sendto_timedwait (handle,
- buf,
- len,
- flags,
- addr,
- addrlen,
- &ts);
- }
+ return ::sendto_timedwait (handle, buf, len, flags, addr, addrlen, ts);
#else
- int val;
- if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
- return -1;
+ int val = 0;
+ if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
+ return -1;
+ else
+ {
+ int bytes_transferred = ACE_OS::sendto (handle, buf, len, flags, addr, addrlen);
+ ACE::restore_non_blocking_mode (handle, val);
+ return bytes_transferred;
+ }
+#endif /* ACE_HAS_SENDTO_TIMEDWAIT */
+ }
+}
+
+ssize_t
+ACE::send_n (ACE_HANDLE handle,
+ const void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout)
+{
+ if (timeout == 0)
+ return ACE::send_n_i (handle,
+ buf,
+ len,
+ flags);
else
+ return ACE::send_n_i (handle,
+ buf,
+ len,
+ flags,
+ timeout);
+}
+
+ssize_t
+ACE::send_n_i (ACE_HANDLE handle,
+ const void *buf,
+ size_t len,
+ int flags)
+{
+ size_t bytes_transferred;
+ ssize_t n;
+
+ for (bytes_transferred = 0;
+ bytes_transferred < len;
+ bytes_transferred += n)
{
- int bytes_written = ACE_OS::sendto (handle,
- buf,
- len,
- flags,
- addr,
- addrlen);
- ACE::leave_send_timedwait (handle, timeout, val);
- return bytes_written;
+ n = ACE_OS::send (handle,
+ (char *) buf + bytes_transferred,
+ len - bytes_transferred,
+ flags);
+ if (n == -1)
+ {
+ // If blocked, try again.
+ if (errno == EWOULDBLOCK)
+ n = 0;
+
+ //
+ // No timeouts in this version.
+ //
+
+ // Other errors.
+ return -1;
+ }
+ else if (n == 0)
+ return 0;
}
-#endif /* ACE_HAS_SENDTO_TIMEDWAIT */
+
+ return bytes_transferred;
}
ssize_t
-ACE::sendmsg (ACE_HANDLE handle,
- const struct msghdr *msg,
- int flags,
- const ACE_Time_Value *timeout)
+ACE::send_n_i (ACE_HANDLE handle,
+ const void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout)
+{
+ int val = 0;
+ ACE::record_and_set_non_blocking_mode (handle, val);
+
+ size_t bytes_transferred;
+ ssize_t n;
+ int error = 0;
+
+ for (bytes_transferred = 0;
+ bytes_transferred < len;
+ bytes_transferred += n)
+ {
+ int result = ACE::handle_write_ready (handle,
+ timeout);
+
+ if (result == -1)
+ {
+ // Timed out; return bytes transferred.
+ if (errno == ETIME)
+ break;
+
+ // Other errors.
+ error = 1;
+ break;
+ }
+
+ n = ACE_OS::send (handle,
+ (char *) buf + bytes_transferred,
+ len - bytes_transferred,
+ flags);
+
+ // Errors (note that errno cannot be EWOULDBLOCK since select()
+ // just told us that data can be written).
+ if (n == -1 || n == 0)
+ {
+ error = 1;
+ break;
+ }
+ }
+
+ ACE::restore_non_blocking_mode (handle, val);
+
+ if (error)
+ return -1;
+ else
+ return bytes_transferred;
+}
+
+ssize_t
+ACE::send_n (ACE_HANDLE handle,
+ const void *buf,
+ size_t len,
+ const ACE_Time_Value *timeout)
{
- // ACE_TRACE ("ACE::sendmsg");
-#if defined (ACE_HAS_SENDMSG_TIMEDWAIT)
if (timeout == 0)
- return ACE_OS::sendmsg (handle, msg, flags);
+ return ACE::send_n_i (handle,
+ buf,
+ len);
else
+ return ACE::send_n_i (handle,
+ buf,
+ len,
+ timeout);
+}
+
+ssize_t
+ACE::send_n_i (ACE_HANDLE handle,
+ const void *buf,
+ size_t len)
+{
+ size_t bytes_transferred;
+ ssize_t n;
+
+ for (bytes_transferred = 0;
+ bytes_transferred < len;
+ bytes_transferred += n)
{
- ACE_Time_Value copy = *timeout;
- copy += ACE_OS::gettimeofday ();
- timespec_t ts = copy;
- return ::sendmsg_timedwait (handle, msg, flags, &ts);
+ n = ACE::send_i (handle,
+ (char *) buf + bytes_transferred,
+ len - bytes_transferred);
+ if (n == -1)
+ {
+ // If blocked, try again.
+ if (errno == EWOULDBLOCK)
+ n = 0;
+
+ //
+ // No timeouts in this version.
+ //
+
+ // Other errors.
+ return -1;
+ }
+ else if (n == 0)
+ return 0;
}
-#else
- int val;
- if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
+
+ return bytes_transferred;
+}
+
+ssize_t
+ACE::send_n_i (ACE_HANDLE handle,
+ const void *buf,
+ size_t len,
+ const ACE_Time_Value *timeout)
+{
+ int val = 0;
+ ACE::record_and_set_non_blocking_mode (handle, val);
+
+ size_t bytes_transferred;
+ ssize_t n;
+ int error = 0;
+
+ for (bytes_transferred = 0;
+ bytes_transferred < len;
+ bytes_transferred += n)
+ {
+ int result = ACE::handle_write_ready (handle,
+ timeout);
+
+ if (result == -1)
+ {
+ // Timed out; return bytes transferred.
+ if (errno == ETIME)
+ break;
+
+ // Other errors.
+ error = 1;
+ break;
+ }
+
+ n = ACE::send_i (handle,
+ (char *) buf + bytes_transferred,
+ len - bytes_transferred);
+
+ // Errors (note that errno cannot be EWOULDBLOCK since select()
+ // just told us that data can be written).
+ if (n == -1 || n == 0)
+ {
+ error = 1;
+ break;
+ }
+ }
+
+ ACE::restore_non_blocking_mode (handle, val);
+
+ if (error)
return -1;
else
+ return bytes_transferred;
+}
+
+// Send N char *ptrs and int lengths. Note that the char *'s precede
+// the ints (basically, an varargs version of writev). The count N is
+// the *total* number of trailing arguments, *not* a couple of the
+// number of tuple pairs!
+
+ssize_t
+ACE::send (ACE_HANDLE handle, size_t n, ...)
+{
+ va_list argp;
+ size_t total_tuples = n / 2;
+ iovec *iovp;
+#if defined (ACE_HAS_ALLOCA)
+ iovp = (iovec *) alloca (total_tuples * sizeof (iovec));
+#else
+ ACE_NEW_RETURN (iovp,
+ iovec[total_tuples],
+ -1);
+#endif /* !defined (ACE_HAS_ALLOCA) */
+
+ va_start (argp, n);
+
+ for (size_t i = 0; i < total_tuples; i++)
{
- int bytes_written = ACE_OS::sendmsg (handle, msg, flags);
- ACE::leave_send_timedwait (handle, timeout, val);
- return bytes_written;
+ iovp[i].iov_base = va_arg (argp, char *);
+ iovp[i].iov_len = va_arg (argp, ssize_t);
}
-#endif /* ACE_HAS_SENDMSG_TIMEDWAIT */
+
+ ssize_t result = ACE_OS::sendv (handle, iovp, total_tuples);
+#if !defined (ACE_HAS_ALLOCA)
+ delete [] iovp;
+#endif /* !defined (ACE_HAS_ALLOCA) */
+ va_end (argp);
+ return result;
}
ssize_t
-ACE::readv (ACE_HANDLE handle,
- iovec *iov,
+ACE::sendv (ACE_HANDLE handle,
+ const iovec *iov,
int iovcnt,
const ACE_Time_Value *timeout)
{
- // ACE_TRACE ("ACE::readv");
-#if defined (ACE_HAS_READV_TIMEDWAIT)
if (timeout == 0)
- return ACE_OS::readv (handle, iov, iovcnt);
- else {
- ACE_Time_Value copy = *timeout;
- copy += ACE_OS::gettimeofday ();
- timespec_t ts = copy;
- return ::readv_timedwait (handle, iov, iovcnt, &ts);
- }
-#else
- int val;
- if (ACE::enter_recv_timedwait (handle, timeout, val) == -1)
- return -1;
+ return ACE_OS::sendv (handle, iov, iovcnt);
else
{
- ssize_t bytes_read = ACE_OS::readv (handle, iov, iovcnt);
- ACE::leave_recv_timedwait (handle, timeout, val);
- return bytes_read;
+#if defined (ACE_HAS_WRITEV_TIMEDWAIT)
+ ACE_Time_Value copy = *timeout;
+ copy += ACE_OS::gettimeofday ();
+ timespec_t ts = copy;
+ return ::sendv_timedwait (handle, iov, iovcnt, &ts);
+#else
+ int val = 0;
+ if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
+ return -1;
+ else
+ {
+ ssize_t bytes_transferred = ACE_OS::sendv (handle, iov, iovcnt);
+ ACE::restore_non_blocking_mode (handle, val);
+ return bytes_transferred;
+ }
+#endif /* ACE_HAS_WRITEV_TIMEDWAIT */
}
-#endif /* ACE_HAS_READV_TIMEDWAIT */
}
ssize_t
-ACE::writev (ACE_HANDLE handle,
- const iovec *iov,
- int iovcnt,
- const ACE_Time_Value *timeout)
+ACE::sendv_n (ACE_HANDLE handle,
+ const iovec *iov,
+ int iovcnt,
+ const ACE_Time_Value *timeout)
{
- // ACE_TRACE ("ACE::writev");
-#if defined (ACE_HAS_WRITEV_TIMEDWAIT)
if (timeout == 0)
- return ACE_OS::writev (handle, iov, iovcnt);
- else {
- ACE_Time_Value copy = *timeout;
- copy += ACE_OS::gettimeofday ();
- timespec_t ts = copy;
- return ::writev_timedwait (handle, iov, iovcnt, &ts);
- }
-#else
- int val;
- if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
- return -1;
+ return ACE::sendv_n_i (handle,
+ iov,
+ iovcnt);
else
+ return ACE::sendv_n_i (handle,
+ iov,
+ iovcnt,
+ timeout);
+}
+
+ssize_t
+ACE::sendv_n_i (ACE_HANDLE handle,
+ const iovec *i,
+ int iovcnt)
+{
+ iovec *iov = ACE_const_cast (iovec *, i);
+
+ ssize_t bytes_transferred = 0;
+
+ for (int s = 0;
+ s < iovcnt;
+ )
{
- ssize_t bytes_written = ACE_OS::writev (handle, iov, iovcnt);
- ACE::leave_send_timedwait (handle, timeout, val);
- return bytes_written;
+ ssize_t n = ACE_OS::sendv (handle,
+ iov + s,
+ iovcnt - s);
+ if (n == -1)
+ {
+ // If blocked, try again.
+ if (errno == EWOULDBLOCK)
+ n = 0;
+
+ //
+ // No timeouts in this version.
+ //
+
+ // Other errors.
+ return -1;
+ }
+ else if (n == 0)
+ return 0;
+
+ for (bytes_transferred += n;
+ s < iovcnt
+ && n >= ACE_static_cast (ssize_t,
+ iov[s].iov_len);
+ s++)
+ n -= iov[s].iov_len;
+
+ if (n != 0)
+ {
+ char *base = ACE_reinterpret_cast (char *,
+ iov[s].iov_base);
+ iov[s].iov_base = base + n;
+ iov[s].iov_len = iov[s].iov_len - n;
+ }
}
-#endif /* ACE_HAS_WRITEV_TIMEDWAIT */
+
+ return bytes_transferred;
}
ssize_t
-ACE::writev_n (ACE_HANDLE h,
- const iovec *i,
- int iovcnt)
+ACE::sendv_n_i (ACE_HANDLE handle,
+ const iovec *i,
+ int iovcnt,
+ const ACE_Time_Value *timeout)
{
- ssize_t writelen = 0;
iovec *iov = ACE_const_cast (iovec *, i);
+ int val = 0;
+ ACE::record_and_set_non_blocking_mode (handle, val);
+
+ ssize_t bytes_transferred = 0;
+ int error = 0;
+
for (int s = 0;
s < iovcnt;
)
{
- ssize_t n = ACE_OS::writev (h,
- iov + s,
- iovcnt - s);
- if (n == -1)
- return n;
- else
+ int result = ACE::handle_write_ready (handle,
+ timeout);
+
+ if (result == -1)
+ {
+ // Timed out; return bytes transferred.
+ if (errno == ETIME)
+ break;
+
+ // Other errors.
+ error = 1;
+ break;
+ }
+
+ ssize_t n = ACE_OS::sendv (handle,
+ iov + s,
+ iovcnt - s);
+
+ // Errors (note that errno cannot be EWOULDBLOCK since select()
+ // just told us that data can be written).
+ if (n == -1 || n == 0)
+ {
+ error = 1;
+ break;
+ }
+
+ for (bytes_transferred += n;
+ s < iovcnt
+ && n >= ACE_static_cast (ssize_t,
+ iov[s].iov_len);
+ s++)
+ n -= iov[s].iov_len;
+
+ if (n != 0)
+ {
+ char *base = ACE_reinterpret_cast (char *,
+ iov[s].iov_base);
+ iov[s].iov_base = base + n;
+ iov[s].iov_len = iov[s].iov_len - n;
+ }
+ }
+
+ ACE::restore_non_blocking_mode (handle, val);
+
+ if (error)
+ return -1;
+ else
+ return bytes_transferred;
+}
+
+ssize_t
+ACE::send (ACE_HANDLE handle,
+ const ACE_Message_Block *message_block,
+ const ACE_Time_Value *timeout)
+{
+ return ACE::send_i (handle,
+ message_block,
+ timeout,
+ 0);
+}
+
+ssize_t
+ACE::send_n (ACE_HANDLE handle,
+ const ACE_Message_Block *message_block,
+ const ACE_Time_Value *timeout)
+{
+ return ACE::send_i (handle,
+ message_block,
+ timeout,
+ 1);
+}
+
+ssize_t
+ACE::send_i (ACE_HANDLE handle,
+ const ACE_Message_Block *message_block,
+ const ACE_Time_Value *timeout,
+ int loop)
+{
+ iovec iov[IOV_MAX];
+ int iovcnt = 0;
+ ssize_t n = 0;
+ ssize_t nbytes = 0;
+ ssize_t send_size = 0;
+
+ while (message_block != 0)
+ {
+ // Check if this block has any data to be sent.
+ if (message_block->length () > 0)
{
- for (writelen += n;
- s < iovcnt
- && n >= ACE_static_cast (ssize_t,
- iov[s].iov_len);
- s++)
- n -= iov[s].iov_len;
+ // Collect the data in the iovec.
+ iov[iovcnt].iov_base = message_block->rd_ptr ();
+ iov[iovcnt].iov_len = message_block->length ();
+
+ // Increment iovec counter.
+ iovcnt++;
- if (n != 0)
+ // Keep track of the number of bytes for this send.
+ send_size += message_block->length ();
+
+ // The buffer is full make a OS call. @@ TODO find a way to
+ // find IOV_MAX for platforms that do not define it rather
+ // than simply setting IOV_MAX to some arbitrary value such
+ // as 16.
+ if (iovcnt == IOV_MAX)
{
- char *base = ACE_reinterpret_cast (char *,
- iov[s].iov_base);
- iov[s].iov_base = base + n;
- iov[s].iov_len = iov[s].iov_len - n;
+ if (loop)
+ n = ACE::sendv_n (handle,
+ iov,
+ iovcnt,
+ timeout);
+ else
+ n = ACE::sendv (handle,
+ iov,
+ iovcnt,
+ timeout);
+
+ // Errors.
+ if (n <= 0)
+ return n;
+
+ // Success. Add to total bytes transferred.
+ nbytes += n;
+
+ // Reset iovec counter.
+ iovcnt = 0;
+
+ // If we sent everything we had accumulated in the last
+ // call, then keep going. If it was a partial send, we
+ // won't continue.
+ if (send_size == n)
+ send_size = 0;
+ else
+ break;
}
}
+
+ // Selection of the next message block: first check the
+ // continuation chain; then look at the next message block in
+ // the queue.
+ if (message_block->cont ())
+ message_block = message_block->cont ();
+ else
+ message_block = message_block->next ();
+ }
+
+ // Check for remaining buffers to be sent. This will happen when
+ // IOV_MAX is not a multiple of the number of message blocks.
+ if (iovcnt != 0)
+ {
+ n = ACE::sendv (handle,
+ iov,
+ iovcnt,
+ timeout);
+
+ // Errors.
+ if (n <= 0)
+ return n;
+
+ // Success. Add to total bytes transferred.
+ nbytes += n;
}
- return writelen;
+ // Return total bytes transferred.
+ return nbytes;
}
ssize_t
-ACE::sendv_n (ACE_HANDLE h,
- const iovec *i,
+ACE::readv_n (ACE_HANDLE handle,
+ iovec *iov,
int iovcnt)
{
- ssize_t writelen = 0;
- iovec *iov = ACE_const_cast (iovec *, i);
+ ssize_t bytes_transferred = 0;
for (int s = 0;
s < iovcnt;
)
{
- ssize_t n = ACE_OS::sendv (h,
+ ssize_t n = ACE_OS::readv (handle,
iov + s,
iovcnt - s);
- if (n == -1)
+ if (n == -1 || n == 0)
return n;
- else
+
+ for (bytes_transferred += n;
+ s < iovcnt
+ && n >= ACE_static_cast (ssize_t,
+ iov[s].iov_len);
+ s++)
+ n -= iov[s].iov_len;
+
+ if (n != 0)
{
- for (writelen += n;
- s < iovcnt
- && n >= ACE_static_cast (ssize_t,
- iov[s].iov_len);
- s++)
- n -= iov[s].iov_len;
+ char *base = ACE_reinterpret_cast (char *,
+ iov[s].iov_base);
+ iov[s].iov_base = base + n;
+ iov[s].iov_len = iov[s].iov_len - n;
+ }
+ }
- if (n != 0)
- {
- char *base = ACE_reinterpret_cast (char *,
- iov[s].iov_base);
- iov[s].iov_base = base + n;
- iov[s].iov_len = iov[s].iov_len - n;
- }
+ return bytes_transferred;
+}
+
+ssize_t
+ACE::writev_n (ACE_HANDLE handle,
+ const iovec *i,
+ int iovcnt)
+{
+ iovec *iov = ACE_const_cast (iovec *, i);
+
+ ssize_t bytes_transferred = 0;
+
+ for (int s = 0;
+ s < iovcnt;
+ )
+ {
+ ssize_t n = ACE_OS::writev (handle,
+ iov + s,
+ iovcnt - s);
+ if (n == -1 || n == 0)
+ return n;
+
+ for (bytes_transferred += n;
+ s < iovcnt
+ && n >= ACE_static_cast (ssize_t,
+ iov[s].iov_len);
+ s++)
+ n -= iov[s].iov_len;
+
+ if (n != 0)
+ {
+ char *base = ACE_reinterpret_cast (char *,
+ iov[s].iov_base);
+ iov[s].iov_base = base + n;
+ iov[s].iov_len = iov[s].iov_len - n;
}
}
- return writelen;
+ return bytes_transferred;
}
+int
+ACE::handle_ready (ACE_HANDLE handle,
+ const ACE_Time_Value *timeout,
+ int read_ready,
+ int write_ready,
+ int exception_ready)
+{
+#if defined (ACE_HAS_POLL) && defined (ACE_HAS_LIMITED_SELECT)
+
+ struct pollfd fds;
+
+ fds.fd = handle;
+ fds.events = read_ready ? POLLIN : POLLOUT;
+ fds.revents = 0;
+
+ int result = ACE_OS::poll (&fds, 1, *timeout);
+
+#else
+
+ ACE_Handle_Set handle_set;
+ handle_set.set_bit (handle);
+
+ // Wait for data or for the timeout to elapse.
+ int result = ACE_OS::select (int (handle) + 1,
+ read_ready ? handle_set.fdset () : 0, // read_fds.
+ write_ready ? handle_set.fdset () : 0, // write_fds.
+ exception_ready ? handle_set.fdset () : 0, // exception_fds.
+ timeout);
+
+#endif /* ACE_HAS_POLL && ACE_HAS_LIMITED_SELECT */
+
+ switch (result)
+ {
+ case 0: // Timer expired.
+ errno = ETIME;
+ /* FALLTHRU */
+ case -1: // we got here directly - select() returned -1.
+ return -1;
+ case 1: // Handle has data.
+ /* FALLTHRU */
+ default: // default is case result > 0; return a
+ // ACE_ASSERT (result == 1);
+ return result;
+ }
+}
+
+int
+ACE::enter_recv_timedwait (ACE_HANDLE handle,
+ const ACE_Time_Value *timeout,
+ int &val)
+{
+ int result = ACE::handle_read_ready (handle,
+ timeout);
+
+ if (result == -1)
+ return -1;
+
+ ACE::record_and_set_non_blocking_mode (handle,
+ val);
+
+ return result;
+}
+
+int
+ACE::enter_send_timedwait (ACE_HANDLE handle,
+ const ACE_Time_Value *timeout,
+ int &val)
+{
+ int result = ACE::handle_write_ready (handle,
+ timeout);
+
+ if (result == -1)
+ return -1;
+
+ ACE::record_and_set_non_blocking_mode (handle,
+ val);
+
+ return result;
+}
+
+void
+ACE::record_and_set_non_blocking_mode (ACE_HANDLE handle,
+ int &val)
+{
+ // We need to record whether we are already *in* nonblocking mode,
+ // so that we can correctly reset the state when we're done.
+ val = ACE::get_flags (handle);
+
+ if (ACE_BIT_DISABLED (val, ACE_NONBLOCK))
+ // Set the handle into non-blocking mode if it's not already in
+ // it.
+ ACE::set_flags (handle, ACE_NONBLOCK);
+}
+
+void
+ACE::restore_non_blocking_mode (ACE_HANDLE handle,
+ int val)
+{
+ if (ACE_BIT_DISABLED (val,
+ ACE_NONBLOCK))
+ {
+ // Save/restore errno.
+ ACE_Errno_Guard error (errno);
+ // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
+ // originally.
+ ACE::clr_flags (handle, ACE_NONBLOCK);
+ }
+}
+
+
// Format buffer into printable format. This is useful for debugging.
// Portions taken from mdump by J.P. Knight (J.P.Knight@lut.ac.uk)
// Modifications by Todd Montgomery.
@@ -2312,329 +3275,6 @@ ACE::map_errno (int error)
return error;
}
-ssize_t
-ACE::send (ACE_HANDLE handle,
- const void *buf,
- size_t n,
- int flags,
- const ACE_Time_Value *timeout)
-{
-#if defined (ACE_HAS_SEND_TIMEDWAIT)
- if (timeout == 0)
- return ACE::send (handle, buf, n, flags);
- else
- {
- ACE_Time_Value copy = *timeout;
- copy += ACE_OS::gettimeofday();
- timespec_t ts = copy;
- return ::send_timedwait (handle, buf, n, flags, &ts);
- }
-#else
- int val;
-
- if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
- return -1;
- else
- {
- ssize_t bytes_written = ACE::send (handle, buf, n, flags);
- ACE::leave_send_timedwait (handle, timeout, val);
- return bytes_written;
- }
-#endif /* ACE_HAS_SEND_TIMEDWAIT */
-}
-
-ssize_t
-ACE::send (ACE_HANDLE handle,
- const void *buf,
- size_t n,
- const ACE_Time_Value *timeout)
-{
- // ACE_TRACE ("ACE_OS::write");
-#if defined (ACE_HAS_WRITE_TIMEDWAIT)
- if (timeout == 0)
- return ACE::send (handle, buf, n);
- else
- {
- ACE_Time_Value copy = *timeout;
- copy += ACE_OS::gettimeofday ();
- timespec_t ts = copy;
- return ::write_timedwait (handle, buf, n, &ts);
- }
-#else
- int val;
-
- if (ACE::enter_send_timedwait (handle, timeout, val) == -1)
- return -1;
- else
- {
- ssize_t bytes_written = ACE::send (handle, buf, n);
- ACE::leave_send_timedwait (handle, timeout, val);
- return bytes_written;
- }
-#endif /* ACE_HAS_WRITE_TIMEDWAIT */
-}
-
-ssize_t
-ACE::send_n (ACE_HANDLE handle,
- const void *buf,
- size_t len,
- int flags,
- const ACE_Time_Value *timeout)
-{
- // Total number of bytes written.
- size_t bytes_written;
-
- // Actual number of bytes written in each <send> attempt.
- ssize_t n;
-
- for (bytes_written = 0;
- bytes_written < len;
- bytes_written += n)
- {
- n = ACE::send (handle,
- (char *) buf + bytes_written,
- len - bytes_written,
- flags,
- timeout);
- if (n == -1)
- if (errno == EWOULDBLOCK)
- n = 0; // Keep trying to send.
- else
- return -1;
- }
-
- return bytes_written;
-}
-
-ssize_t
-ACE::send_n (ACE_HANDLE handle,
- const void *buf,
- size_t len,
- const ACE_Time_Value *timeout)
-{
- // Total number of bytes written.
- size_t bytes_written;
-
- // Actual number of bytes written in each <send> attempt.
- ssize_t n;
-
- for (bytes_written = 0;
- bytes_written < len;
- bytes_written += n)
- {
- n = ACE::send (handle, (char *) buf + bytes_written,
- len - bytes_written, timeout);
- if (n == -1)
- if (errno == EWOULDBLOCK)
- n = 0; // Keep trying to send.
- else
- return -1;
- }
-
- return bytes_written;
-}
-
-ssize_t
-ACE::recvfrom (ACE_HANDLE handle,
- char *buf,
- int len,
- int flags,
- struct sockaddr *addr,
- int *addrlen,
- const ACE_Time_Value *timeout)
-{
- // ACE_TRACE ("ACE::recvfrom");
-#if defined (ACE_HAS_RECVFROM_TIMEDWAIT)
- if (timeout == 0)
- return ACE_OS::recvfrom (handle,
- buf,
- len,
- flags,
- addr,
- addrlen);
- else
- {
- ACE_Time_Value copy = *timeout;
- copy += ACE_OS::gettimeofday ();
- timespec_t ts = copy;
- return ::recvfrom_timedwait (handle,
- buf,
- len,
- flags,
- addr,
- addrlen,
- &ts)a
-;
- }
-#else
- int val;
- if (ACE::enter_recv_timedwait (handle,
- timeout,
- val) == -1)
- return -1;
- else
- {
- int bytes_read = ACE_OS::recvfrom (handle,
- buf,
- len,
- flags,
- addr,
- addrlen);
- ACE::leave_recv_timedwait (handle,
- timeout,
- val);
- return bytes_read;
- }
-#endif /* ACE_HAS_RECVFROM_TIMEDWAIT */
-}
-
-ssize_t
-ACE::recvmsg (ACE_HANDLE handle,
- struct msghdr *msg,
- int flags,
- const ACE_Time_Value *timeout)
-{
- // ACE_TRACE ("ACE::recvmsg");
-#if defined (ACE_HAS_RECVMSG_TIMEDWAIT)
- if (timeout == 0)
- return ACE_OS::recvmsg (handle, msg, flags);
- else
- {
- ACE_Time_Value copy = *timeout;
- copy += ACE_OS::gettimeofday ();
- timespec_t ts = copy;
- return ::recvmsg_timedwait (handle, msg, flags, &ts);
- }
-#else
- int val;
- if (ACE::enter_recv_timedwait (handle, timeout, val) == -1)
- return -1;
- else
- {
- int bytes_read = ACE_OS::recvmsg (handle, msg, flags);
- ACE::leave_recv_timedwait (handle, timeout, val);
- return bytes_read;
- }
-#endif /* ACE_HAS_RECVMSG_TIMEDWAIT */
-}
-
-ssize_t
-ACE::recv (ACE_HANDLE handle,
- void *buf,
- size_t n,
- const ACE_Time_Value *timeout)
-{
- // ACE_TRACE ("ACE::read");
-#if defined (ACE_HAS_READ_TIMEDWAIT)
- if (timeout == 0)
- return ACE::recv (handle, buf, n);
- else
- {
- ACE_Time_Value copy = *timeout;
- copy += ACE_OS::gettimeofday ();
- timespec_t ts = copy;
- return ::read_timedwait (handle, buf, n, &ts);
- }
-#else
- int val;
-
- if (ACE::enter_recv_timedwait (handle, timeout, val) == -1)
- return -1;
- else
- {
- ssize_t bytes_read = ACE::recv (handle, buf, n);
- ACE::leave_recv_timedwait (handle, timeout, val);
- return bytes_read;
- }
-#endif /* ACE_HAS_READ_TIMEDWAIT */
-}
-
-ssize_t
-ACE::recv (ACE_HANDLE handle,
- void *buf,
- size_t len,
- int flags,
- const ACE_Time_Value *timeout)
-{
- // ACE_TRACE ("ACE::recv");
-#if defined (ACE_HAS_RECV_TIMEDWAIT)
- if (timeout == 0)
- return ACE::recv (handle, buf, len, flags);
- else
- {
- ACE_Time_Value copy = *timeout;
- copy += ACE_OS::gettimeofday ();
- timespec_t ts = copy;
- return ::recv_timedwait (handle, buf, len, flags, &ts);
- }
-#else
- int val;
- if (ACE::enter_recv_timedwait (handle, timeout, val)==-1)
- return -1;
- else
- {
- ssize_t bytes_recv = ACE::recv (handle, buf, len, flags);
- ACE::leave_recv_timedwait (handle, timeout, val);
- return bytes_recv;
- }
-#endif /* ACE_HAS_RECV_TIMEDWAIT */
-}
-
-ssize_t
-ACE::recv_n (ACE_HANDLE handle,
- void *buf,
- size_t len,
- int flags,
- const ACE_Time_Value *timeout)
-{
- size_t bytes_received;
-
- // Actual number of bytes read in each attempt.
- ssize_t n;
-
- for (bytes_received = 0;
- bytes_received < len;
- bytes_received += n)
- {
- n = ACE::recv (handle,
- (char *) buf + bytes_received,
- len - bytes_received,
- flags,
- timeout);
- if (n == -1 || n == 0)
- break;
- }
-
- return bytes_received;
-}
-
-ssize_t
-ACE::recv_n (ACE_HANDLE handle,
- void *buf,
- size_t len,
- const ACE_Time_Value *timeout)
-{
- size_t bytes_received;
-
- // Actual number of bytes read in each attempt.
- ssize_t n;
-
- for (bytes_received = 0;
- bytes_received < len;
- bytes_received += n)
- {
- n = ACE::recv (handle,
- (char *) buf + bytes_received,
- len - bytes_received,
- timeout);
- if (n == -1 || n == 0)
- break;
- }
-
- return bytes_received;
-}
-
-
// Euclid's greatest common divisor algorithm.
u_long
ACE::gcd (u_long x, u_long y)
diff --git a/ace/ACE.h b/ace/ACE.h
index c6ad68687ee..6ff3e15750e 100644
--- a/ace/ACE.h
+++ b/ace/ACE.h
@@ -27,6 +27,7 @@
// Forward declarations.
class ACE_Time_Value;
class ACE_INET_Addr;
+class ACE_Message_Block;
class ACE_Export ACE
{
@@ -77,75 +78,56 @@ public:
// Check if error indicates the process being out of handles (file
// descriptors).
- // = Recv operations that factor out differences between Win32 and UNIX.
- static ssize_t recv (ACE_HANDLE handle,
- void *buf,
- size_t len,
- int flags);
- // Receive up to <len> bytes into <buf> from <handle> (uses the
- // <ACE_OS::recv> call).
-
- static ssize_t recv (ACE_HANDLE handle,
- void *buf,
- size_t len);
- // Receive up to <len> bytes into <buf> from <handle> (uses the
- // <ACE_OS::read> system call on UNIX and the <ACE_OS::recv> call on
- // Win32).
-
- // = Recv operations that receive exactly n bytes.
- static ssize_t recv_n (ACE_HANDLE handle,
- void *buf,
- size_t len,
- int flags);
- // Receive <len> bytes into <buf> from <handle> (uses the
- // <ACE_OS::recv> call). If <handle> is set to non-blocking mode
- // this call will poll until all <len> bytes are received.
+ // = I/O operations.
- static ssize_t recv_n (ACE_HANDLE handle,
- void *buf,
- size_t len);
- // Receive <len> bytes into <buf> from <handle> (uses the
- // <ACE_OS::read> system call on UNIX and the <ACE_OS::recv> call on
- // Win32). If <handle> is set to non-blocking mode this call will
- // poll until all <len> bytes are received.
+ // = Notes on common parameters:
+ //
+ // <handle> is the connected endpoint that will be used for I/O.
+ //
+ // <buf> is the buffer to write from or receive into.
+ //
+ // <len> is the number of bytes to transfer.
+ //
+ // The <timeout> parameter in the following methods indicates how
+ // long to blocking trying to transfer data. If <timeout> == 0,
+ // then the call behaves as a normal send/recv call, i.e., for
+ // blocking sockets, the call will block until action is possible;
+ // for non-blocking sockets, EWOULDBLOCK will be returned if no
+ // action is immediately possible.
+ //
+ // If <timeout> != 0, the call will wait until the relative time
+ // specified in *<timeout> elapses.
+ //
+ // Errors are reported by -1 and 0 return values. If the operation
+ // times out, -1 is returned with <errno == ETIME>. If it succeeds
+ // the number of bytes transferred is returned.
+ //
+ // The "_n" I/O methods keep looping until all the data has been
+ // transferred. These methods also work for sockets in non-blocking
+ // mode i.e., they keep looping on EWOULDBLOCK. <timeout> is used
+ // to make sure we keep making progress, i.e., the same timeout
+ // value is used for every I/O operation in the loop and the timeout
+ // is not counted down. If the transfer times out, the number of
+ // bytes transferred so far are returned.
+ //
+ // Methods with <iovec> parameter are I/O vector variants of the I/O
+ // operations.
- // = Timed <recv> operations.
static ssize_t recv (ACE_HANDLE handle,
void *buf,
size_t len,
int flags,
- const ACE_Time_Value *timeout);
- // Wait up to <timeout> amount of time to receive up to <len> bytes
- // into <buf> from <handle> (uses the <ACE_OS::recv> call). The
- // <timeout> indicates how long to blocking trying to receive. If
- // <timeout> == 0, the caller will block until action is possible,
- // else will wait until the relative time specified in *<timeout>
- // elapses). If <recv> times out a -1 is returned with <errno ==
- // ETIME>. If it succeeds the number of bytes received is returned.
+ const ACE_Time_Value *timeout = 0);
static ssize_t recv (ACE_HANDLE handle,
void *buf,
size_t len,
- const ACE_Time_Value *timeout);
- // Wait up to <timeout> amount of time to receive up to <len> bytes
- // into <buf> from <handle> (uses the <ACE_OS::read> call). The
- // <timeout> indicates how long to blocking trying to receive. If
- // <timeout> == 0, the caller will block until action is possible,
- // else will wait until the relative time specified in *<timeout>
- // elapses). If <recv> times out a -1 is returned with <errno ==
- // ETIME>. If it succeeds the number of bytes received is returned.
+ const ACE_Time_Value *timeout = 0);
static ssize_t recvmsg (ACE_HANDLE handle,
struct msghdr *msg,
int flags,
- const ACE_Time_Value *timeout);
- // Wait up to <timeout> amount of time to receive <msg> from
- // <handle> (uses the <ACE_OS::recvmsg> call). The <timeout>
- // indicates how long to blocking trying to receive. If <timeout>
- // == 0, the caller will block until action is possible, else will
- // wait until the relative time specified in *<timeout> elapses).
- // If <recvmsg> times out a -1 is returned with <errno == ETIME>.
- // If it succeeds the number of bytes received is returned.
+ const ACE_Time_Value *timeout = 0);
static ssize_t recvfrom (ACE_HANDLE handle,
char *buf,
@@ -153,107 +135,55 @@ public:
int flags,
struct sockaddr *addr,
int *addrlen,
- const ACE_Time_Value *timeout);
- // Wait up to <timeout> amount of time to recv up to <len> bytes
- // into <buf> from <handle> (uses the <ACE_OS::recvfrom> call). The
- // <timeout> indicates how long to blocking trying to recv. If
- // <timeout> == 0, the caller will block until action is possible,
- // else will wait until the relative time specified in *<timeout>
- // elapses). If <recvfrom> times out a -1 is returned with <errno
- // == ETIME>. If it succeeds the number of bytes received is
- // returned.
+ const ACE_Time_Value *timeout = 0);
static ssize_t recv_n (ACE_HANDLE handle,
void *buf,
size_t len,
int flags,
- const ACE_Time_Value *timeout);
- // Try to recv exactly <len> bytes into <buf> from <handle> (uses
- // the <ACE_OS::recv> call). The <timeout> indicates how long to
- // blocking trying to receive. If <timeout> == 0, the caller will
- // block until action is possible, else will wait until the relative
- // time specified in *<timeout> elapses). If <recv> blocks for
- // longer than <timeout> the number of bytes actually read is
- // returned with <errno == ETIME>. If a timeout does not occur,
- // <recv_n> return <len> (i.e., the number of bytes requested to be
- // read).
+ const ACE_Time_Value *timeout = 0);
static ssize_t recv_n (ACE_HANDLE handle,
void *buf,
size_t len,
- const ACE_Time_Value *timeout);
- // Try to recv exactly <len> bytes into <buf> from <handle> (uses
- // the <ACE_OS::recv> call). The <timeout> indicates how long to
- // blocking trying to receive. If <timeout> == 0, the caller will
- // block until action is possible, else will wait until the relative
- // time specified in *<timeout> elapses). If <recv> blocks for
- // longer than <timeout> the number of bytes actually read is
- // returned with <errno == ETIME>. If a timeout does not occur,
- // <recv_n> return <len> (i.e., the number of bytes requested to be
- // read).
-
- // = Send operations that factor out differences between Win32 and UNIX.
- static ssize_t send (ACE_HANDLE handle,
- const void *buf,
- size_t len,
- int flags);
- // Send up to <len> bytes into <buf> from <handle> (uses the
- // <ACE_OS::send> call).
+ const ACE_Time_Value *timeout = 0);
- static ssize_t send (ACE_HANDLE handle,
- const void *buf,
- size_t len);
- // Send up to <len> bytes into <buf> from <handle> (uses the
- // <ACE_OS::write> system call on UNIX and the <ACE_OS::send> call
- // on Win32).
+ static ssize_t recv (ACE_HANDLE handle, size_t n, ...);
+ // Varargs variant.
- // = Send operations that send exactly n bytes.
- static ssize_t send_n (ACE_HANDLE handle,
- const void *buf,
- size_t len,
- int flags);
- // Send <len> bytes from <buf> to <handle> (uses the <ACE_OS::send>
- // system call). If <handle> is set to non-blocking mode this call
- // will poll until all <len> bytes are sent.
+ static ssize_t recvv (ACE_HANDLE handle,
+ iovec *iov,
+ int iovcnt,
+ const ACE_Time_Value *timeout = 0);
+
+ static ssize_t recvv_n (ACE_HANDLE handle,
+ iovec *iov,
+ int iovcnt,
+ const ACE_Time_Value *timeout = 0);
+
+ static ssize_t recv (ACE_HANDLE handle,
+ ACE_Message_Block *message_block,
+ const ACE_Time_Value *timeout = 0);
+
+ static ssize_t recv_n (ACE_HANDLE handle,
+ ACE_Message_Block *message_block,
+ const ACE_Time_Value *timeout = 0);
- // = Timed <send> operations.
static ssize_t send (ACE_HANDLE handle,
const void *buf,
size_t len,
- const ACE_Time_Value *timeout);
- // Wait up to <timeout> amount of time to send up to <len> bytes
- // into <buf> from <handle> (uses the <ACE_OS::write> system call on
- // UNIX and the <ACE_OS::send> call on Win32). The <timeout>
- // indicates how long to blocking trying to send. If <timeout> ==
- // 0, the caller will block until action is possible, else will wait
- // until the relative time specified in *<timeout> elapses). If
- // <send> times out a -1 is returned with <errno == ETIME>. If it
- // succeeds the number of bytes sent is returned.
+ const ACE_Time_Value *timeout = 0);
static ssize_t send (ACE_HANDLE handle,
const void *buf,
size_t len,
int flags,
- const ACE_Time_Value *timeout);
- // Wait up to <timeout> amount of time to send up to <len> bytes
- // into <buf> from <handle> (uses the <ACE_OS::send> call). The
- // <timeout> indicates how long to blocking trying to send. If
- // <timeout> == 0, the caller will block until action is possible,
- // else will wait until the relative time specified in *<timeout>
- // elapses). If <send> times out a -1 is returned with <errno ==
- // ETIME>. If it succeeds the number of bytes sent is returned.
+ const ACE_Time_Value *timeout = 0);
static ssize_t sendmsg (ACE_HANDLE handle,
const struct msghdr *msg,
int flags,
- const ACE_Time_Value *timeout);
- // Wait up to <timeout> amount of time to send the <msg> to <handle>
- // (uses the <ACE_OS::sendmsg> call). The <timeout> indicates how
- // long to blocking trying to send. If <timeout> == 0, the caller
- // will block until action is possible, else will wait until the
- // relative time specified in *<timeout> elapses). If <sendmsg>
- // times out a -1 is returned with <errno == ETIME>. If it succeeds
- // the number of bytes sent is returned.
+ const ACE_Time_Value *timeout = 0);
static ssize_t sendto (ACE_HANDLE handle,
const char *buf,
@@ -261,101 +191,41 @@ public:
int flags,
const struct sockaddr *addr,
int addrlen,
- const ACE_Time_Value *timeout);
- // Wait up to <timeout> amount of time to send up to <len> bytes
- // into <buf> from <handle> (uses the <ACE_OS::sendto> call). The
- // <timeout> indicates how long to blocking trying to send. If
- // <timeout> == 0, the caller will block until action is possible,
- // else will wait until the relative time specified in *<timeout>
- // elapses). If <sendto> times out a -1 is returned with <errno ==
- // ETIME>. If it succeeds the number of bytes sent is returned.
+ const ACE_Time_Value *timeout = 0);
static ssize_t send_n (ACE_HANDLE handle,
const void *buf,
size_t len,
int flags,
- const ACE_Time_Value *timeout);
- // Try to send exactly <len> bytes into <buf> from <handle> (uses
- // the <ACE_OS::send> call). The <timeout> indicates how long to
- // blocking trying to send. If <timeout> == 0, the caller will
- // block until action is possible, else will wait until the relative
- // time specified in *<timeout> elapses). If <send> blocks for
- // longer than <timeout> the number of bytes actually sent is
- // returned with <errno == ETIME>. If a timeout does not occur,
- // <send_n> return <len> (i.e., the number of bytes requested to be
- // sent).
+ const ACE_Time_Value *timeout = 0);
static ssize_t send_n (ACE_HANDLE handle,
const void *buf,
size_t len,
- const ACE_Time_Value *timeout);
- // Try to send exactly <len> bytes into <buf> from <handle> (uses
- // the <ACE_OS::send> call). The <timeout> indicates how long to
- // blocking trying to send. If <timeout> == 0, the caller will
- // block until action is possible, else will wait until the relative
- // time specified in *<timeout> elapses). If <send> blocks for
- // longer than <timeout> the number of bytes actually sent is
- // returned with <errno == ETIME>. If a timeout does not occur,
- // <send_n> return <len> (i.e., the number of bytes requested to be
- // sent).
-
- // = Timed Scatter-read and gather-write functions.
-
- static ssize_t sendv_n (ACE_HANDLE handle,
- const iovec *iov,
- int iovcnt);
- // Send all <iovcnt> <iovec> structs to <handle> (uses the
- // <ACE_OS::sendv> call). If it succeeds the number of bytes
- // written is returned, else -1 is returned.
-
- static ssize_t writev (ACE_HANDLE handle,
- const iovec *iov,
- int iovcnt,
const ACE_Time_Value *timeout = 0);
- // Send <iovcnt> <iovec> structs to <handle> (uses the
- // <ACE_OS::writev> call). If <timeout> == 0, the caller will block
- // until action is possible, else will wait until the relative time
- // specified in *<timeout> elapses). If <writev> times out a -1 is
- // returned with <errno == ETIME>. If it succeeds the number of
- // bytes written is returned.
- static ssize_t writev_n (ACE_HANDLE handle,
- const iovec *iov,
- int iovcnt);
- // Send all <iovcnt> <iovec> structs to <handle> (uses the
- // <ACE_OS::writev> call). If it succeeds the number of bytes
- // written is returned, else -1 is returned.
+ static ssize_t send (ACE_HANDLE handle, size_t n, ...);
+ // Varargs variant.
- static ssize_t readv (ACE_HANDLE handle,
- iovec *iov,
+ static ssize_t sendv (ACE_HANDLE handle,
+ const iovec *iov,
int iovcnt,
const ACE_Time_Value *timeout = 0);
- // Read <iovcnt> <iovec> structs from <handle> (uses the
- // <ACE_OS::readv> call). If <timeout> == 0, the caller will block
- // until action is possible, else will wait until the relative time
- // specified in *<timeout> elapses). If <readv> times out a -1 is
- // returned with <errno == ETIME>. If it succeeds the number of
- // bytes receieved is returned.
-
- static ssize_t send (ACE_HANDLE handle, size_t n, ...);
- // Send varargs messages to the <handle> using <writev>.
- static ssize_t recv (ACE_HANDLE handle, size_t n, ...);
- // Recv varargs messages to the <handle> using <readv>.
-
- // = File system I/O functions.
+ static ssize_t sendv_n (ACE_HANDLE handle,
+ const iovec *iov,
+ int iovcnt,
+ const ACE_Time_Value *timeout = 0);
- // These encapsulate differences between UNIX and Win32 and also
- // send and recv exactly n bytes. The definitions have been moved
- // to ACE_OS; these remain for backward compatiblity.
+ static ssize_t send (ACE_HANDLE handle,
+ const ACE_Message_Block *message_block,
+ const ACE_Time_Value *timeout = 0);
static ssize_t send_n (ACE_HANDLE handle,
- const void *buf,
- size_t len);
- // Send <len> bytes from <buf> to <handle> (uses the <ACE_OS::write>
- // system call on UNIX and the <ACE_OS::recv> call on Win32). If
- // <handle> is set to non-blocking mode this call will poll until
- // all <len> bytes are sent.
+ const ACE_Message_Block *message_block,
+ const ACE_Time_Value *timeout = 0);
+
+ // = File system I/O functions (these don't support timeouts).
static ssize_t read_n (ACE_HANDLE handle,
void *buf,
@@ -365,6 +235,14 @@ public:
const void *buf,
size_t len);
+ static ssize_t readv_n (ACE_HANDLE handle,
+ iovec *iov,
+ int iovcnt);
+
+ static ssize_t writev_n (ACE_HANDLE handle,
+ const iovec *iov,
+ int iovcnt);
+
// = Socket connection establishment calls.
static int bind_port (ACE_HANDLE handle,
@@ -680,30 +558,132 @@ public:
static char debug (void);
static void debug (char d);
-private:
+ static int handle_read_ready (ACE_HANDLE handle,
+ const ACE_Time_Value *timeout);
+ // Timed wait for handle to get read ready.
+
+ static int handle_write_ready (ACE_HANDLE handle,
+ const ACE_Time_Value *timeout);
+ // Timed wait for handle to get write ready.
+
+ static int handle_exception_ready (ACE_HANDLE handle,
+ const ACE_Time_Value *timeout);
+ // Timed wait for handle to get exception ready.
+
+ static int handle_ready (ACE_HANDLE handle,
+ const ACE_Time_Value *timeout,
+ int read_ready,
+ int write_ready,
+ int exception_ready);
+ // Timed wait for handle to get read, write, or exception ready.
+
static int enter_recv_timedwait (ACE_HANDLE handle,
const ACE_Time_Value *timeout,
int &val);
// Wait for <timeout> before proceeding to a <recv> operation.
// <val> keeps track of whether we're in non-blocking mode or not.
- static void leave_recv_timedwait (ACE_HANDLE handle,
- const ACE_Time_Value *timeout,
- int val);
- // Cleanup after a <recv> operation (e.g., restore the appropriate
- // non-blocking status of <handle>).
-
static int enter_send_timedwait (ACE_HANDLE handle,
const ACE_Time_Value* timeout,
int &val);
// Wait for <timeout> before proceeding to a <send> operation.
// <val> keeps track of whether we're in non-blocking mode or not.
- static void leave_send_timedwait (ACE_HANDLE handle,
- const ACE_Time_Value *timeout,
- int val);
- // Cleanup after the <send> operation (e.g., restore the appropriate
- // non-blocking status of <handle>).
+ static void record_and_set_non_blocking_mode (ACE_HANDLE handle,
+ int &val);
+ // This makes sure that <handle> is set into non-blocking mode.
+ // <val> keeps track of whether were in non-blocking mode or not.
+
+ static void restore_non_blocking_mode (ACE_HANDLE handle,
+ int val);
+ // Cleanup after a timed operation, restore the appropriate
+ // non-blocking status of <handle>.
+
+private:
+
+ //
+ // = Recv_n helpers
+ //
+
+ static ssize_t recv_i (ACE_HANDLE handle,
+ void *buf,
+ size_t len);
+
+ static ssize_t recv_n_i (ACE_HANDLE handle,
+ void *buf,
+ size_t len,
+ int flags);
+
+ static ssize_t recv_n_i (ACE_HANDLE handle,
+ void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout);
+
+ static ssize_t recv_n_i (ACE_HANDLE handle,
+ void *buf,
+ size_t len);
+
+ static ssize_t recv_n_i (ACE_HANDLE handle,
+ void *buf,
+ size_t len,
+ const ACE_Time_Value *timeout);
+
+ static ssize_t recvv_n_i (ACE_HANDLE handle,
+ iovec *iov,
+ int iovcnt);
+
+ static ssize_t recvv_n_i (ACE_HANDLE handle,
+ iovec *iov,
+ int iovcnt,
+ const ACE_Time_Value *timeout);
+
+ static ssize_t recv_i (ACE_HANDLE handle,
+ ACE_Message_Block *message_block,
+ const ACE_Time_Value *timeout,
+ int loop);
+
+ //
+ // = Send_n helpers
+ //
+
+ static ssize_t send_i (ACE_HANDLE handle,
+ const void *buf,
+ size_t len);
+
+ static ssize_t send_n_i (ACE_HANDLE handle,
+ const void *buf,
+ size_t len,
+ int flags);
+
+ static ssize_t send_n_i (ACE_HANDLE handle,
+ const void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout);
+
+ static ssize_t send_n_i (ACE_HANDLE handle,
+ const void *buf,
+ size_t len);
+
+ static ssize_t send_n_i (ACE_HANDLE handle,
+ const void *buf,
+ size_t len,
+ const ACE_Time_Value *timeout);
+
+ static ssize_t sendv_n_i (ACE_HANDLE handle,
+ const iovec *iov,
+ int iovcnt);
+
+ static ssize_t sendv_n_i (ACE_HANDLE handle,
+ const iovec *iov,
+ int iovcnt,
+ const ACE_Time_Value *timeout);
+
+ static ssize_t send_i (ACE_HANDLE handle,
+ const ACE_Message_Block *message_block,
+ const ACE_Time_Value *timeout,
+ int loop);
static u_int init_fini_count_;
// Counter to match <init>/<fini> calls. <init> must increment it;
diff --git a/ace/ACE.i b/ace/ACE.i
index a7f6e541661..8d69ea3a139 100644
--- a/ace/ACE.i
+++ b/ace/ACE.i
@@ -8,33 +8,20 @@ ACE::read_n (ACE_HANDLE handle,
void *buf,
size_t len)
{
- ACE_TRACE ("ACE::read_n");
return ACE_OS::read_n (handle, buf, len);
}
ASYS_INLINE ssize_t
-ACE::send_n (ACE_HANDLE handle, const void *buf, size_t len)
-{
- ACE_TRACE ("ACE::send_n");
- return ACE_OS::send_n (handle, buf, len);
-}
-
-ASYS_INLINE ssize_t
ACE::write_n (ACE_HANDLE handle,
const void *buf,
size_t len)
{
- ACE_TRACE ("ACE::write_n");
return ACE_OS::write_n (handle, buf, len);
}
-// Miscellaneous static methods used throughout ACE.
-
ASYS_INLINE ssize_t
-ACE::send (ACE_HANDLE handle, const void *buf, size_t len)
+ACE::send_i (ACE_HANDLE handle, const void *buf, size_t len)
{
- ACE_TRACE ("ACE::send");
-
#if defined (ACE_WIN32) || defined (ACE_PSOS)
return ACE_OS::send (handle, (const char *) buf, len);
#else
@@ -43,16 +30,8 @@ ACE::send (ACE_HANDLE handle, const void *buf, size_t len)
}
ASYS_INLINE ssize_t
-ACE::send (ACE_HANDLE handle, const void *buf, size_t len, int flags)
-{
- ACE_TRACE ("ACE::send");
- return ACE_OS::send (handle, (const char *) buf, len, flags);
-}
-
-ASYS_INLINE ssize_t
-ACE::recv (ACE_HANDLE handle, void *buf, size_t len)
+ACE::recv_i (ACE_HANDLE handle, void *buf, size_t len)
{
- ACE_TRACE ("ACE::recv");
#if defined (ACE_WIN32) || defined (ACE_PSOS)
return ACE_OS::recv (handle, (char *) buf, len);
#else
@@ -60,12 +39,37 @@ ACE::recv (ACE_HANDLE handle, void *buf, size_t len)
#endif /* ACE_WIN32 */
}
-ASYS_INLINE ssize_t
-ACE::recv (ACE_HANDLE handle, void *buf, size_t len, int flags)
+ASYS_INLINE int
+ACE::handle_read_ready (ACE_HANDLE handle,
+ const ACE_Time_Value *timeout)
{
- ACE_TRACE ("ACE::recv");
+ return ACE::handle_ready (handle,
+ timeout,
+ 1,
+ 0,
+ 0);
+}
- return ACE_OS::recv (handle, (char *) buf, len, flags);
+ASYS_INLINE int
+ACE::handle_write_ready (ACE_HANDLE handle,
+ const ACE_Time_Value *timeout)
+{
+ return ACE::handle_ready (handle,
+ timeout,
+ 0,
+ 1,
+ 0);
+}
+
+ASYS_INLINE int
+ACE::handle_exception_ready (ACE_HANDLE handle,
+ const ACE_Time_Value *timeout)
+{
+ return ACE::handle_ready (handle,
+ timeout,
+ 0,
+ 0,
+ 1);
}
ASYS_INLINE char *
diff --git a/ace/Handle_Set.h b/ace/Handle_Set.h
index a131eabdd15..79811ebc81f 100644
--- a/ace/Handle_Set.h
+++ b/ace/Handle_Set.h
@@ -27,7 +27,7 @@ class ACE_Export ACE_Handle_Set
{
// = TITLE
// C++ wrapper facade for the socket <fd_set> abstraction.
- //
+ //
// = DESCRIPTION
// This abstraction is a very efficient wrapper facade over
// <fd_set>. In particular, no range checking is performed, so
@@ -85,6 +85,10 @@ public:
// Returns a pointer to the underlying <fd_set>. Returns 0 if
// <size_> == 0.
+ fd_set *fdset (void);
+ // Returns a pointer to the underlying <fd_set>. Returns 0 if
+ // <size_> == 0.
+
#if defined (ACE_HAS_BIG_FD_SET)
ACE_Handle_Set & operator= (const ACE_Handle_Set &);
// Assignment operator optimizes for cases where <size_> == 0.
diff --git a/ace/Handle_Set.i b/ace/Handle_Set.i
index 2076b8ff622..676731ac0bc 100644
--- a/ace/Handle_Set.i
+++ b/ace/Handle_Set.i
@@ -13,7 +13,7 @@ ACE_Handle_Set::~ACE_Handle_Set (void)
}
#endif /* ACE_HAS_WINCE */
-ACE_INLINE void
+ACE_INLINE void
ACE_Handle_Set::reset (void)
{
ACE_TRACE ("ACE_Handle_Set::reset");
@@ -55,7 +55,7 @@ ACE_Handle_Set::operator= (const ACE_Handle_Set &rhs)
// Returns the number of the large bit.
-ACE_INLINE ACE_HANDLE
+ACE_INLINE ACE_HANDLE
ACE_Handle_Set::max_set (void) const
{
ACE_TRACE ("ACE_Handle_Set::max_set");
@@ -70,7 +70,7 @@ ACE_Handle_Set::is_set (ACE_HANDLE handle) const
ACE_TRACE ("ACE_Handle_Set::is_set");
#if defined (ACE_HAS_BIG_FD_SET)
return FD_ISSET (handle,
- &this->mask_)
+ &this->mask_)
&& this->size_ > 0;
#else
return FD_ISSET (handle,
@@ -80,7 +80,7 @@ ACE_Handle_Set::is_set (ACE_HANDLE handle) const
// Enables the handle.
-ACE_INLINE void
+ACE_INLINE void
ACE_Handle_Set::set_bit (ACE_HANDLE handle)
{
ACE_TRACE ("ACE_Handle_Set::set_bit");
@@ -93,25 +93,25 @@ ACE_Handle_Set::set_bit (ACE_HANDLE handle)
#else /* ACE_WIN32 */
#if defined (ACE_HAS_BIG_FD_SET)
if (this->size_ == 0)
- FD_ZERO (&this->mask_);
+ FD_ZERO (&this->mask_);
if (handle < this->min_handle_)
this->min_handle_ = handle;
#endif /* ACE_HAS_BIG_FD_SET */
-
+
FD_SET (handle,
&this->mask_);
this->size_++;
-
+
if (handle > this->max_handle_)
- this->max_handle_ = handle;
+ this->max_handle_ = handle;
#endif /* ACE_WIN32 */
}
}
// Disables the handle.
-ACE_INLINE void
+ACE_INLINE void
ACE_Handle_Set::clr_bit (ACE_HANDLE handle)
{
ACE_TRACE ("ACE_Handle_Set::clr_bit");
@@ -121,17 +121,17 @@ ACE_Handle_Set::clr_bit (ACE_HANDLE handle)
FD_CLR ((ACE_SOCKET) handle,
&this->mask_);
this->size_--;
-
+
#if !defined (ACE_WIN32)
if (handle == this->max_handle_)
- this->set_max (this->max_handle_);
+ this->set_max (this->max_handle_);
#endif /* !ACE_WIN32 */
}
}
// Returns a count of the number of enabled bits.
-ACE_INLINE int
+ACE_INLINE int
ACE_Handle_Set::num_set (void) const
{
ACE_TRACE ("ACE_Handle_Set::num_set");
@@ -155,6 +155,19 @@ ACE_Handle_Set::operator fd_set *()
return (fd_set *) NULL;
}
+// Returns a pointer to the underlying fd_set.
+
+ACE_INLINE fd_set *
+ACE_Handle_Set::fdset (void)
+{
+ ACE_TRACE ("ACE_Handle_Set::operator ACE_FD_SET_TYPE *");
+
+ if (this->size_ > 0)
+ return (fd_set *) &this->mask_;
+ else
+ return (fd_set *) NULL;
+}
+
ACE_INLINE
ACE_Handle_Set_Iterator::~ACE_Handle_Set_Iterator (void)
{
diff --git a/ace/OS.cpp b/ace/OS.cpp
index b43f5826314..f87d1235249 100644
--- a/ace/OS.cpp
+++ b/ace/OS.cpp
@@ -4254,98 +4254,48 @@ ACE_OS::fork_exec (ASYS_TCHAR *argv[])
# endif /* ACE_WIN32 */
}
-// Receive <len> bytes into <buf> from <handle> (uses the <read>
-// system call on UNIX and the <ReadFile> call on Win32).
-
ssize_t
ACE_OS::read_n (ACE_HANDLE handle,
void *buf,
size_t len)
{
- ACE_TRACE ("ACE_OS::read_n");
-
- size_t bytes_read;
+ size_t bytes_transferred;
ssize_t n;
- for (bytes_read = 0; bytes_read < len; bytes_read += n)
+ for (bytes_transferred = 0;
+ bytes_transferred < len;
+ bytes_transferred += n)
{
n = ACE_OS::read (handle,
- (char *) buf + bytes_read,
- len - bytes_read);
-
- if (n == -1)
- {
- if (errno == EWOULDBLOCK)
- n = 0; // Keep trying to read.
- else
- return -1;
- }
- else if (n == 0)
- break;
+ (char *) buf + bytes_transferred,
+ len - bytes_transferred);
+ if (n == -1 || n == 0)
+ return n;
}
- return bytes_read;
+ return bytes_transferred;
}
ssize_t
-ACE_OS::send_n (ACE_HANDLE handle, const void *buf, size_t len)
-{
- ACE_TRACE ("ACE_OS::send_n");
- size_t bytes_written;
- ssize_t n;
-
- for (bytes_written = 0; bytes_written < len; bytes_written += n)
- {
- n =
-#if defined (ACE_WIN32) || defined (ACE_PSOS)
- ACE_OS::send (handle,
- (const char *) buf + bytes_written,
- len - bytes_written);
-#else
- ACE_OS::write (handle,
- (const char *) buf + bytes_written,
- len - bytes_written);
-#endif /* ACE_WIN32 */
-
- if (n == -1)
- {
- if (errno == EWOULDBLOCK)
- n = 0; // Keep trying to send.
- else
- return -1;
- }
- }
-
- return bytes_written;
-}
-
-// Write <len> bytes from <buf> to <handle> (uses the <write>
-// system call on UNIX and the <WriteFile> call on Win32).
-
-ssize_t
ACE_OS::write_n (ACE_HANDLE handle,
const void *buf,
size_t len)
{
- ACE_TRACE ("ACE_OS::write_n");
-
- size_t bytes_written;
+ size_t bytes_transferred;
ssize_t n;
- for (bytes_written = 0; bytes_written < len; bytes_written += n)
+ for (bytes_transferred = 0;
+ bytes_transferred < len;
+ bytes_transferred += n)
{
- n = ACE_OS::write (handle, (const char *) buf + bytes_written,
- len - bytes_written);
- if (n == -1)
- {
- if (errno == EWOULDBLOCK)
- n = 0; // Keep trying to send.
- else
- return -1;
- }
+ n = ACE_OS::write (handle,
+ (char *) buf + bytes_transferred,
+ len - bytes_transferred);
+ if (n == -1 || n == 0)
+ return n;
}
- return bytes_written;
+ return bytes_transferred;
}
# if defined (ACE_LACKS_WRITEV)
@@ -4386,7 +4336,7 @@ writev (ACE_HANDLE handle, ACE_WRITEV_TYPE iov[], int n)
ptr += iov[i].iov_len;
}
- ssize_t result = ACE_OS::write_n (handle, buf, length);
+ ssize_t result = ACE_OS::write (handle, buf, length);
# if !defined (ACE_HAS_ALLOCA)
delete [] buf;
# endif /* !defined (ACE_HAS_ALLOCA) */
@@ -4424,7 +4374,7 @@ ACE_TRACE ("readv");
-1);
# endif /* !defined (ACE_HAS_ALLOCA) */
- length = ACE_OS::read_n (handle, buf, length);
+ length = ACE_OS::read (handle, buf, length);
if (length != -1)
{
diff --git a/ace/OS.h b/ace/OS.h
index 5e456789afc..cb3886efdac 100644
--- a/ace/OS.h
+++ b/ace/OS.h
@@ -6345,11 +6345,8 @@ public:
ACE_OVERLAPPED_COMPLETION_FUNC func);
static int send (ACE_HANDLE handle,
const char *buf,
- int len, int
- flags = 0);
- static ssize_t send_n (ACE_HANDLE handle,
- const void *buf,
- size_t len);
+ int len,
+ int flags = 0);
static int sendto (ACE_HANDLE handle,
const char *buf,
int len,
@@ -7141,16 +7138,19 @@ int putchar (int c);
# endif /* ACE_HAS_WINCE */
# if defined (ACE_LACKS_TIMEDWAIT_PROTOTYPES)
-extern "C" ssize_t send_timedwait (ACE_HANDLE handle,
- const char *buf,
- int len,
- int flags,
- struct timespec *timeout);
extern "C" ssize_t recv_timedwait (ACE_HANDLE handle,
char *buf,
int len,
int flags,
struct timespec *timeout);
+extern "C" ssize_t read_timedwait (ACE_HANDLE handle,
+ char *buf,
+ size_t n,
+ struct timespec *timeout);
+extern "C" ssize_t recvmsg_timedwait (ACE_HANDLE handle,
+ struct msghdr *msg,
+ int flags,
+ struct timespec *timeout);
extern "C" ssize_t recvfrom_timedwait (ACE_HANDLE handle,
char *buf,
int len,
@@ -7159,14 +7159,23 @@ extern "C" ssize_t recvfrom_timedwait (ACE_HANDLE handle,
int
*addrlen,
struct timespec *timeout);
-extern "C" ssize_t recvmsg_timedwait (ACE_HANDLE handle,
- struct msghdr *msg,
+extern "C" ssize_t readv_timedwait (ACE_HANDLE handle,
+ iovec *iov,
+ int iovcnt,
+ struct timespec* timeout);
+extern "C" ssize_t send_timedwait (ACE_HANDLE handle,
+ const char *buf,
+ int len,
+ int flags,
+ struct timespec *timeout);
+extern "C" ssize_t write_timedwait (ACE_HANDLE handle,
+ const void *buf,
+ size_t n,
+ struct timespec *timeout);
+extern "C" ssize_t sendmsg_timedwait (ACE_HANDLE handle,
+ ACE_SENDMSG_TYPE *msg,
int flags,
struct timespec *timeout);
-extern "C" ssize_t read_timedwait (ACE_HANDLE handle,
- void *buf,
- size_t len,
- struct timespec *timeout);
extern "C" ssize_t sendto_timedwait (ACE_HANDLE handle,
const char *buf,
int len,
@@ -7174,18 +7183,6 @@ extern "C" ssize_t sendto_timedwait (ACE_HANDLE handle,
const struct sockaddr *addr,
int addrlen,
struct timespec *timeout);
-extern "C" ssize_t sendmsg_timedwait (ACE_HANDLE handle,
- ACE_SENDMSG_TYPE *msg,
- int flags,
- struct timespec *timeout);
-extern "C" ssize_t write_timedwait (ACE_HANDLE handle,
- const void *buf,
- size_t n,
- struct timespec *timeout);
-extern "C" ssize_t readv_timedwait (ACE_HANDLE handle,
- iovec *iov,
- int iovcnt,
- struct timespec* timeout);
extern "C" ssize_t writev_timedwait (ACE_HANDLE handle,
ACE_WRITEV_TYPE *iov,
int iovcnt,
diff --git a/ace/SOCK_Dgram.cpp b/ace/SOCK_Dgram.cpp
index ea499be700d..590e07650b8 100644
--- a/ace/SOCK_Dgram.cpp
+++ b/ace/SOCK_Dgram.cpp
@@ -26,9 +26,9 @@ ACE_SOCK_Dgram::dump (void) const
// returns the number of bytes read.
ssize_t
-ACE_SOCK_Dgram::recv (iovec io_vec[],
- ACE_Addr &addr,
- int flags,
+ACE_SOCK_Dgram::recv (iovec io_vec[],
+ ACE_Addr &addr,
+ int flags,
const ACE_Time_Value *timeout) const
{
ACE_TRACE ("ACE_SOCK_Dgram::recv");
@@ -60,7 +60,7 @@ ACE_SOCK_Dgram::recv (iovec io_vec[],
int addr_len = addr.get_size ();
u_long inlen;
- if (ACE_OS::ioctl (this->get_handle (),
+ if (ACE_OS::ioctl (this->get_handle (),
FIONREAD, (u_long *) &inlen) == -1)
return -1;
else if (inlen > 0)
@@ -69,16 +69,16 @@ ACE_SOCK_Dgram::recv (iovec io_vec[],
char[inlen],
-1);
io_vec->iov_len = ACE_OS::recvfrom (this->get_handle (),
- (char *) io_vec->iov_base,
- inlen,
- flags,
- (sockaddr *) saddr,
+ (char *) io_vec->iov_base,
+ inlen,
+ flags,
+ (sockaddr *) saddr,
&addr_len);
addr.set_size (addr_len);
return io_vec->iov_len;
}
else
- return 0;
+ return 0;
#else
ACE_UNUSED_ARG (flags);
ACE_UNUSED_ARG (addr);
@@ -94,13 +94,13 @@ ACE_SOCK_Dgram::recv (iovec io_vec[],
// to a portnumber.
int
-ACE_SOCK_Dgram::shared_open (const ACE_Addr &local,
- int protocol_family)
+ACE_SOCK_Dgram::shared_open (const ACE_Addr &local,
+ int protocol_family)
{
ACE_TRACE ("ACE_SOCK_Dgram::shared_open");
int error = 0;
- if (local == ACE_Addr::sap_any
+ if (local == ACE_Addr::sap_any
&& protocol_family == PF_INET)
{
if (ACE::bind_port (this->get_handle ()) == -1)
@@ -119,8 +119,8 @@ ACE_SOCK_Dgram::shared_open (const ACE_Addr &local,
}
int
-ACE_SOCK_Dgram::open (const ACE_Addr &local,
- int protocol_family,
+ACE_SOCK_Dgram::open (const ACE_Addr &local,
+ int protocol_family,
int protocol,
ACE_Protocol_Info *protocolinfo,
ACE_SOCK_GROUP g,
@@ -128,7 +128,7 @@ ACE_SOCK_Dgram::open (const ACE_Addr &local,
int reuse_addr)
{
if (ACE_SOCK::open (SOCK_DGRAM,
- protocol_family,
+ protocol_family,
protocol,
protocolinfo,
g,
@@ -145,14 +145,14 @@ ACE_SOCK_Dgram::open (const ACE_Addr &local,
// Here's the general-purpose open routine.
int
-ACE_SOCK_Dgram::open (const ACE_Addr &local,
- int protocol_family,
+ACE_SOCK_Dgram::open (const ACE_Addr &local,
+ int protocol_family,
int protocol,
int reuse_addr)
{
ACE_TRACE ("ACE_SOCK_Dgram::open");
if (ACE_SOCK::open (SOCK_DGRAM,
- protocol_family,
+ protocol_family,
protocol,
reuse_addr) == -1)
return -1;
@@ -164,8 +164,8 @@ ACE_SOCK_Dgram::open (const ACE_Addr &local,
// Here's the general-purpose constructor used by a connectionless
// datagram ``server''...
-ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr &local,
- int protocol_family,
+ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr &local,
+ int protocol_family,
int protocol,
int reuse_addr)
{
@@ -180,8 +180,8 @@ ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr &local,
ASYS_TEXT ("ACE_SOCK_Dgram")));
}
-ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr &local,
- int protocol_family,
+ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr &local,
+ int protocol_family,
int protocol,
ACE_Protocol_Info *protocolinfo,
ACE_SOCK_GROUP g,
@@ -206,13 +206,13 @@ ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr &local,
// version).
ssize_t
-ACE_SOCK_Dgram::send (const iovec iov[],
- size_t n,
- const ACE_Addr &addr,
+ACE_SOCK_Dgram::send (const iovec iov[],
+ size_t n,
+ const ACE_Addr &addr,
int flags) const
{
ACE_TRACE ("ACE_SOCK_Dgram::send");
- msghdr send_msg;
+ msghdr send_msg;
send_msg.msg_iov = (iovec *) iov;
send_msg.msg_iovlen = n;
@@ -226,7 +226,7 @@ ACE_SOCK_Dgram::send (const iovec iov[],
#if defined (ACE_HAS_4_4BSD_SENDMSG_RECVMSG)
send_msg.msg_control = 0;
send_msg.msg_controllen = 0;
- send_msg.msg_flags = 0;
+ send_msg.msg_flags = 0;
#else
send_msg.msg_accrights = 0;
send_msg.msg_accrightslen = 0;
@@ -241,13 +241,13 @@ ACE_SOCK_Dgram::send (const iovec iov[],
// version).
ssize_t
-ACE_SOCK_Dgram::recv (iovec iov[],
- size_t n,
- ACE_Addr &addr,
+ACE_SOCK_Dgram::recv (iovec iov[],
+ size_t n,
+ ACE_Addr &addr,
int flags) const
{
ACE_TRACE ("ACE_SOCK_Dgram::recv");
- msghdr recv_msg;
+ msghdr recv_msg;
recv_msg.msg_iov = (iovec *) iov;
recv_msg.msg_iovlen = n;
@@ -266,7 +266,7 @@ ACE_SOCK_Dgram::recv (iovec iov[],
recv_msg.msg_accrightslen = 0;
#endif /* ACE_HAS_4_4BSD_SENDMSG_RECVMSG */
- ssize_t status = ACE_OS::recvmsg (this->get_handle (),
+ ssize_t status = ACE_OS::recvmsg (this->get_handle (),
&recv_msg,
flags);
addr.set_size (recv_msg.msg_namelen);
@@ -279,9 +279,9 @@ ACE_SOCK_Dgram::recv (iovec iov[],
// version).
ssize_t
-ACE_SOCK_Dgram::send (const iovec iov[],
- size_t n,
- const ACE_Addr &addr,
+ACE_SOCK_Dgram::send (const iovec iov[],
+ size_t n,
+ const ACE_Addr &addr,
int flags) const
{
ACE_TRACE ("ACE_SOCK_Dgram::send");
@@ -304,7 +304,7 @@ ACE_SOCK_Dgram::send (const iovec iov[],
#if defined (ACE_HAS_ALLOCA)
buf = alloca (length);
-#else
+#else
ACE_NEW_RETURN (buf,
char[length],
-1);
@@ -329,9 +329,9 @@ ACE_SOCK_Dgram::send (const iovec iov[],
// version).
ssize_t
-ACE_SOCK_Dgram::recv (iovec iov[],
- size_t n,
- ACE_Addr &addr,
+ACE_SOCK_Dgram::recv (iovec iov[],
+ size_t n,
+ ACE_Addr &addr,
int flags) const
{
ACE_TRACE ("ACE_SOCK_Dgram::recv");
@@ -353,7 +353,7 @@ ACE_SOCK_Dgram::recv (iovec iov[],
#if defined (ACE_HAS_ALLOCA)
buf = alloca (length);
-#else
+#else
ACE_NEW_RETURN (buf,
char[length],
-1);
@@ -365,19 +365,19 @@ ACE_SOCK_Dgram::recv (iovec iov[],
{
char *ptr = buf;
int copyn = length;
-
- for (i = 0;
- i < n && copyn > 0;
- i++)
- {
- ACE_OS::memcpy (iov[i].iov_base, ptr,
+
+ for (i = 0;
+ i < n && copyn > 0;
+ i++)
+ {
+ ACE_OS::memcpy (iov[i].iov_base, ptr,
// iov_len is int on some platforms, size_t on others
- copyn > (int) iov[i].iov_len
+ copyn > (int) iov[i].iov_len
? (size_t) iov[i].iov_len
: (size_t) copyn);
- ptr += iov[i].iov_len;
- copyn -= iov[i].iov_len;
- }
+ ptr += iov[i].iov_len;
+ copyn -= iov[i].iov_len;
+ }
}
#if !defined (ACE_HAS_ALLOCA)
@@ -388,12 +388,12 @@ ACE_SOCK_Dgram::recv (iovec iov[],
#endif /* ACE_HAS_MSG */
-ssize_t
-ACE_SOCK_Dgram::recv (void *buf,
- size_t n,
- ACE_Addr &addr,
- int flags,
- const ACE_Time_Value *timeout) const
+ssize_t
+ACE_SOCK_Dgram::recv (void *buf,
+ size_t n,
+ ACE_Addr &addr,
+ int flags,
+ const ACE_Time_Value *timeout) const
{
ACE_Handle_Set handle_set;
handle_set.reset ();
@@ -401,9 +401,10 @@ ACE_SOCK_Dgram::recv (void *buf,
// Check the status of the current socket.
switch (ACE_OS::select (int (this->get_handle ()) + 1,
- handle_set,
- 0, 0,
- timeout))
+ handle_set,
+ 0,
+ 0,
+ timeout))
{
case -1:
return -1;
@@ -417,3 +418,34 @@ ACE_SOCK_Dgram::recv (void *buf,
return this->recv (buf, n, addr, flags);
}
}
+
+ssize_t
+ACE_SOCK_Dgram::send (const void *buf,
+ size_t n,
+ ACE_Addr &addr,
+ int flags,
+ const ACE_Time_Value *timeout) const
+{
+ ACE_Handle_Set handle_set;
+ handle_set.reset ();
+ handle_set.set_bit (this->get_handle ());
+
+ // Check the status of the current socket.
+ switch (ACE_OS::select (int (this->get_handle ()) + 1,
+ 0,
+ handle_set,
+ 0,
+ timeout))
+ {
+ case -1:
+ return -1;
+ /* NOTREACHED */
+ case 0:
+ errno = ETIME;
+ return -1;
+ /* NOTREACHED */
+ default:
+ // Goes fine, call <send> to get data
+ return this->send (buf, n, addr, flags);
+ }
+}
diff --git a/ace/SOCK_Dgram.h b/ace/SOCK_Dgram.h
index 111434a3d7e..af31f35a287 100644
--- a/ace/SOCK_Dgram.h
+++ b/ace/SOCK_Dgram.h
@@ -126,6 +126,19 @@ public:
// returned with <errno == ETIME>. If it succeeds the number of
// bytes received is returned.
+ ssize_t send (const void *buf,
+ size_t n,
+ ACE_Addr &addr,
+ int flags,
+ const ACE_Time_Value *timeout) const;
+ // Wait up to <timeout> amount of time to receive a datagram into
+ // <buf>. The <ACE_Time_Value> indicates how long to blocking
+ // trying to receive. If <timeout> == 0, the caller will block
+ // until action is possible, else will wait until the relative time
+ // specified in *<timeout> elapses). If <send> times out a -1 is
+ // returned with <errno == ETIME>. If it succeeds the number of
+ // bytes received is returned.
+
ssize_t send (const iovec buffers[],
int buffer_count,
size_t &number_of_bytes_sent,
diff --git a/ace/SOCK_IO.cpp b/ace/SOCK_IO.cpp
index 2431033c70d..1bac103df6d 100644
--- a/ace/SOCK_IO.cpp
+++ b/ace/SOCK_IO.cpp
@@ -26,7 +26,7 @@ ACE_SOCK_IO::dump (void) const
ssize_t
ACE_SOCK_IO::recvv (iovec *io_vec,
- const ACE_Time_Value *timeout)
+ const ACE_Time_Value *timeout) const
{
ACE_TRACE ("ACE_SOCK_IO::recvv");
#if defined (FIONREAD)
@@ -147,8 +147,8 @@ ACE_SOCK_IO::recv (size_t n, ...) const
iovp[i].iov_len = va_arg (argp, ssize_t);
}
- ssize_t result = ACE_OS::recvv (this->get_handle (),
- iovp,
+ ssize_t result = ACE_OS::recvv (this->get_handle (),
+ iovp,
total_tuples);
#if !defined (ACE_HAS_ALLOCA)
delete [] iovp;
diff --git a/ace/SOCK_IO.h b/ace/SOCK_IO.h
index d3a29106c8e..f7bb6b7454a 100644
--- a/ace/SOCK_IO.h
+++ b/ace/SOCK_IO.h
@@ -28,6 +28,27 @@ class ACE_Export ACE_SOCK_IO : public ACE_SOCK
// = TITLE
// Defines the methods for the ACE socket wrapper I/O routines
// (e.g., send/recv).
+ //
+ // = NOTES
+ //
+ // If <timeout> == 0, then the call behaves as a normal
+ // send/recv call, i.e., for blocking sockets, the call will
+ // block until action is possible; for non-blocking sockets,
+ // EWOULDBLOCK will be returned if no action is immediately
+ // possible.
+ //
+ // If <timeout> != 0, the call will wait until the relative time
+ // specified in *<timeout> elapses.
+ //
+ // Errors are reported by -1 and 0 return values. If the
+ // operation times out, -1 is returned with <errno == ETIME>.
+ // If it succeeds the number of bytes transferred is returned.
+ //
+ // Methods with the extra <flags> argument will always result in
+ // <send> getting called. Methods without the extra <flags>
+ // argument will result in <send> getting called on Win32
+ // platforms, and <write> getting called on non-Win32 platforms.
+ //
public:
// = Initialization and termination methods.
@@ -37,38 +58,29 @@ public:
~ACE_SOCK_IO (void);
// Destructor.
- ssize_t send (const void *buf,
- size_t n,
- int flags) const;
- // Send an <n> byte buffer to the connected socket (uses
- // <send(3n)>).
-
ssize_t recv (void *buf,
size_t n,
- int flags) const;
- // Recv an <n> byte buffer from the connected socket (uses
- // <recv(3n)>).
-
- ssize_t send (const void *buf,
- size_t n) const;
- // Send an <n> byte buffer to the connected socket (uses
- // <write(2)>).
+ int flags,
+ const ACE_Time_Value *timeout = 0) const;
+ // Recv an <n> byte buffer from the connected socket.
ssize_t recv (void *buf,
- size_t n) const;
- // Recv an <n> byte buffer from the connected socket (uses
- // <read(2)>).
+ size_t n,
+ const ACE_Time_Value *timeout = 0) const;
+ // Recv an <n> byte buffer from the connected socket.
- ssize_t sendv (const iovec iov[],
- size_t n) const;
- // Send an <iovec> of size <n> to the connected socket.
+ ssize_t recvv (iovec iov[],
+ size_t n,
+ const ACE_Time_Value *timeout = 0) const;
+ // Recv an <iovec> of size <n> from the connected socket.
- ssize_t send (const iovec iov[],
- size_t n) const;
+ ssize_t recv (iovec iov[],
+ size_t n,
+ const ACE_Time_Value *timeout = 0) const;
// Same as above. Deprecated.
ssize_t recvv (iovec *io_vec,
- const ACE_Time_Value *timeout = 0);
+ const ACE_Time_Value *timeout = 0) const;
// Allows a client to read from a socket without having to provide a
// buffer to read. This method determines how much data is in the
// socket, allocates a buffer of this size, reads in the data, and
@@ -77,61 +89,48 @@ public:
// delete [] io_vec->iov_base.
ssize_t recv (iovec *io_vec,
- const ACE_Time_Value *timeout = 0);
+ const ACE_Time_Value *timeout = 0) const;
// Same as above. Deprecated.
- ssize_t send (const void *buf,
- size_t n,
- int flags,
- const ACE_Time_Value *timeout) const;
- // Wait to to <timeout> amount of time to send up to <n> bytes into
- // <buf> from <handle> (uses the <send> call). If <send> times out
- // a -1 is returned with <errno == ETIME>. If it succeeds the
- // number of bytes sent is returned.
+ ssize_t recv (size_t n,
+ ...) const;
+ // Recv <n> varargs messages to the connected socket.
ssize_t recv (void *buf,
size_t n,
+ ACE_OVERLAPPED *overlapped) const;
+ // Recv <n> bytes via Win32 <ReadFile> using overlapped I/O.
+
+ ssize_t send (const void *buf,
+ size_t n,
int flags,
- const ACE_Time_Value *timeout) const;
- // Wait up to <timeout> amount of time to receive up to <n> bytes
- // into <buf> from <handle> (uses the <recv> call). If <recv> times
- // out a -1 is returned with <errno == ETIME>. If it succeeds the
- // number of bytes received is returned.
+ const ACE_Time_Value *timeout = 0) const;
+ // Send an <n> byte buffer to the connected socket.
ssize_t send (const void *buf,
size_t n,
- const ACE_Time_Value *timeout) const;
- // Wait to to <timeout> amount of time to send up to <n> bytes into
- // <buf> from <handle> (uses the <send> call). If <send> times out
- // a -1 is returned with <errno == ETIME>. If it succeeds the
- // number of bytes sent is returned.
+ const ACE_Time_Value *timeout = 0) const;
+ // Send an <n> byte buffer to the connected socket.
- ssize_t recv (void *buf,
+ ssize_t sendv (const iovec iov[],
+ size_t n,
+ const ACE_Time_Value *timeout = 0) const;
+ // Send an <iovec> of size <n> to the connected socket.
+
+ ssize_t send (const iovec iov[],
size_t n,
- const ACE_Time_Value *timeout) const;
- // Wait up to <timeout> amount of time to receive up to <n> bytes
- // into <buf> from <handle> (uses the <recv> call). If <recv> times
- // out a -1 is returned with <errno == ETIME>. If it succeeds the
- // number of bytes received is returned.
+ const ACE_Time_Value *timeout = 0) const;
+ // Same as above. Deprecated.
ssize_t send (size_t n,
...) const;
// Send <n> varargs messages to the connected socket.
- ssize_t recv (size_t n,
- ...) const;
- // Recv <n> varargs messages to the connected socket.
-
ssize_t send (const void *buf,
size_t n,
ACE_OVERLAPPED *overlapped) const;
// Send <n> bytes via Win32 <WriteFile> using overlapped I/O.
- ssize_t recv (void *buf,
- size_t n,
- ACE_OVERLAPPED *overlapped) const;
- // Recv <n> bytes via Win32 <ReadFile> using overlapped I/O.
-
void dump (void) const;
// Dump the state of an object.
diff --git a/ace/SOCK_IO.i b/ace/SOCK_IO.i
index db41f079cd7..d46ca3c188f 100644
--- a/ace/SOCK_IO.i
+++ b/ace/SOCK_IO.i
@@ -18,87 +18,72 @@ ACE_SOCK_IO::~ACE_SOCK_IO (void)
}
ASYS_INLINE ssize_t
-ACE_SOCK_IO::send (const void *buf, size_t n, int flags) const
-{
- ACE_TRACE ("ACE_SOCK_IO::send");
- return ACE_OS::send (this->get_handle (), (const char *) buf, n, flags);
-}
-
-// Recv an n byte message from the connected socket.
-
-ASYS_INLINE ssize_t
-ACE_SOCK_IO::recv (void *buf, size_t n, int flags) const
+ACE_SOCK_IO::recv (void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout) const
{
ACE_TRACE ("ACE_SOCK_IO::recv");
- return ACE_OS::recv (this->get_handle (), (char *) buf, n, flags);
+ return ACE::recv (this->get_handle (),
+ buf,
+ len,
+ flags,
+ timeout);
}
-// Send an n byte message to the connected socket.
-
ASYS_INLINE ssize_t
-ACE_SOCK_IO::send (const void *buf, size_t n) const
-{
- ACE_TRACE ("ACE_SOCK_IO::send");
-#if defined (ACE_WIN32)
- return ACE_OS::send (this->get_handle (), (const char *) buf, n, 0);
-#else
- return ACE_OS::write (this->get_handle (), (const char *) buf, n);
-#endif /* ACE_WIN32 */
-}
-
-// Recv an n byte message from the connected socket.
-
-ASYS_INLINE ssize_t
-ACE_SOCK_IO::recv (void *buf, size_t n) const
+ACE_SOCK_IO::recv (void *buf,
+ size_t len,
+ const ACE_Time_Value *timeout) const
{
ACE_TRACE ("ACE_SOCK_IO::recv");
-#if defined (ACE_WIN32)
- return ACE_OS::recv (this->get_handle (), (char *) buf, n, 0);
-#else
- return ACE_OS::read (this->get_handle (), (char *) buf, n);
-#endif /* ACE_WIN32 */
+ return ACE::recv (this->get_handle (),
+ buf,
+ len,
+ timeout);
}
-// Send a vector of n byte messages to the connected socket.
-
ASYS_INLINE ssize_t
-ACE_SOCK_IO::sendv (const iovec iov[], size_t n) const
+ACE_SOCK_IO::recvv (iovec iov[],
+ size_t n,
+ const ACE_Time_Value *timeout) const
{
- ACE_TRACE ("ACE_SOCK_IO::sendv");
- return ACE_OS::sendv (this->get_handle (), iov, n);
+ ACE_TRACE ("ACE_SOCK_IO::recvv");
+ return ACE::recvv (this->get_handle (),
+ iov,
+ n,
+ timeout);
}
ASYS_INLINE ssize_t
-ACE_SOCK_IO::send (const iovec iov[], size_t n) const
+ACE_SOCK_IO::recv (iovec iov[],
+ size_t n,
+ const ACE_Time_Value *timeout) const
{
- ACE_TRACE ("ACE_SOCK_IO::send");
- return this->sendv (iov, n);
+ ACE_TRACE ("ACE_SOCK_IO::recv");
+ return this->recvv (iov,
+ n,
+ timeout);
}
ASYS_INLINE ssize_t
ACE_SOCK_IO::recv (iovec *io_vec,
- const ACE_Time_Value *timeout)
+ const ACE_Time_Value *timeout) const
{
ACE_TRACE ("ACE_SOCK_IO::recv");
- return this->recvv (io_vec, timeout);
+ return this->recvv (io_vec,
+ timeout);
}
ASYS_INLINE ssize_t
-ACE_SOCK_IO::send (const void *buf, size_t n,
- ACE_OVERLAPPED *overlapped) const
-{
- ACE_TRACE ("ACE_SOCK_IO::send");
- return ACE_OS::write (this->get_handle (),
- (const char *) buf, n,
- overlapped);
-}
-
-ASYS_INLINE ssize_t
-ACE_SOCK_IO::recv (void *buf, size_t n,
+ACE_SOCK_IO::recv (void *buf,
+ size_t n,
ACE_OVERLAPPED *overlapped) const
{
ACE_TRACE ("ACE_SOCK_IO::recv");
- return ACE_OS::read (this->get_handle (), (char *) buf, n,
+ return ACE_OS::read (this->get_handle (),
+ (char *) buf,
+ n,
overlapped);
}
@@ -109,33 +94,56 @@ ACE_SOCK_IO::send (const void *buf,
const ACE_Time_Value *timeout) const
{
ACE_TRACE ("ACE_SOCK_IO::send");
- return ACE::send (this->get_handle (), buf, len, flags, timeout);
+ return ACE::send (this->get_handle (),
+ buf,
+ len,
+ flags,
+ timeout);
}
ASYS_INLINE ssize_t
-ACE_SOCK_IO::recv (void *buf,
+ACE_SOCK_IO::send (const void *buf,
size_t len,
const ACE_Time_Value *timeout) const
{
- ACE_TRACE ("ACE_SOCK_IO::recv");
- return ACE::recv (this->get_handle (), buf, len, timeout);
+ ACE_TRACE ("ACE_SOCK_IO::send");
+ return ACE::send (this->get_handle (),
+ buf,
+ len,
+ timeout);
}
ASYS_INLINE ssize_t
-ACE_SOCK_IO::send (const void *buf,
- size_t len,
+ACE_SOCK_IO::sendv (const iovec iov[],
+ size_t n,
+ const ACE_Time_Value *timeout) const
+{
+ ACE_TRACE ("ACE_SOCK_IO::sendv");
+ return ACE::sendv (this->get_handle (),
+ iov,
+ n,
+ timeout);
+}
+
+ASYS_INLINE ssize_t
+ACE_SOCK_IO::send (const iovec iov[],
+ size_t n,
const ACE_Time_Value *timeout) const
{
ACE_TRACE ("ACE_SOCK_IO::send");
- return ACE::send (this->get_handle (), buf, len, timeout);
+ return this->sendv (iov,
+ n,
+ timeout);
}
ASYS_INLINE ssize_t
-ACE_SOCK_IO::recv (void *buf,
- size_t len,
- int flags,
- const ACE_Time_Value *timeout) const
+ACE_SOCK_IO::send (const void *buf,
+ size_t n,
+ ACE_OVERLAPPED *overlapped) const
{
- ACE_TRACE ("ACE_SOCK_IO::recv");
- return ACE::recv (this->get_handle (), buf, len, flags, timeout);
+ ACE_TRACE ("ACE_SOCK_IO::send");
+ return ACE_OS::write (this->get_handle (),
+ (const char *) buf,
+ n,
+ overlapped);
}
diff --git a/ace/SOCK_Stream.h b/ace/SOCK_Stream.h
index 1e1982a8ebe..504caf6f73e 100644
--- a/ace/SOCK_Stream.h
+++ b/ace/SOCK_Stream.h
@@ -33,6 +33,25 @@ class ACE_Export ACE_SOCK_Stream : public ACE_SOCK_IO
// = DESCRIPTION
// This adds additional wrapper methods atop the <ACE_SOCK_IO>
// class.
+ //
+ // = NOTES
+ //
+ // The "_n" I/O methods keep looping until all the data has been
+ // transferred. These methods also work for sockets in
+ // non-blocking mode i.e., they keep looping on EWOULDBLOCK.
+ // <timeout> is used to make sure we keep making progress, i.e.,
+ // the same timeout value is used for every I/O operation in the
+ // loop and the timeout is not counted down. If the transfer
+ // times out, the number of bytes transferred so far are
+ // returned.
+ //
+ // Errors are reported by -1 and 0 return values.
+ //
+ // Methods with the extra <flags> argument will always result in
+ // <send> getting called. Methods without the extra <flags>
+ // argument will result in <send> getting called on Win32
+ // platforms, and <write> getting called on non-Win32 platforms.
+ //
public:
// Initialization and termination methods.
ACE_SOCK_Stream (void);
@@ -44,55 +63,48 @@ public:
~ACE_SOCK_Stream (void);
// Destructor.
- //= The following two methods use write and read system calls.
- ssize_t send_n (const void *buf, int n) const;
- // Send n bytes, keep trying until n are sent.
- ssize_t recv_n (void *buf, int n) const;
- // Recv n bytes, keep trying until n are received.
-
- // = The following two methods use the send and recv system calls.
- ssize_t send_n (const void *buf, int n, int flags) const;
- // Send n bytes, keep trying until n are sent.
- ssize_t recv_n (void *buf, int n, int flags) const;
- // Recv n bytes, keep trying until n are received.
+ // = I/O functions.
- ssize_t send_n (const void *buf,
+ ssize_t recv_n (void *buf,
size_t len,
int flags,
- const ACE_Time_Value *timeout);
- // Try to send exactly <len> bytes into <buf> from <handle> (uses
- // the <send> call). If <send> blocks for longer than <timeout> the
- // number of bytes actually sent is returned with <errno == ETIME>.
- // If a timeout does not occur, <send_n> return <len> (i.e., the
- // number of bytes requested to be sent).
+ const ACE_Time_Value *timeout = 0) const;
+ // Try to recv exactly <len> bytes into <buf> from <handle>.
ssize_t recv_n (void *buf,
size_t len,
- int flags,
- const ACE_Time_Value *timeout);
- // Try to recv exactly <len> bytes into <buf> from <handle> (uses
- // the <ACE::recv_n> call). The <ACE_Time_Value> indicates how long
- // to blocking trying to receive. If <timeout> == 0, the caller
- // will block until action is possible, else will wait until the
- // relative time specified in *<timeout> elapses). If <recv> blocks
- // for longer than <timeout> the number of bytes actually read is
- // returned with <errno == ETIME>. If a timeout does not occur,
- // <recv_n> return <len> (i.e., the number of bytes requested to be
- // read).
-
- ssize_t sendv_n (const iovec iov[],
- size_t n) const;
- // Send an <iovec> of size <n> to the connected socket (uses
- // <ACE::sendv_n>). Will block until all bytes are sent or an error
- // occurs.
+ const ACE_Time_Value *timeout = 0) const;
+ // Try to recv exactly <len> bytes into <buf> from <handle>.
ssize_t recvv_n (iovec iov[],
- size_t n) const;
- // Receive an <iovec> of size <n> to the connected socket.
+ size_t iovcnt,
+ const ACE_Time_Value *timeout = 0) const;
+ // Receive an <iovec> of size <iovcnt> to the connected socket.
- // = Send/receive an ``urgent'' character (see TCP specs...).
- ssize_t send_urg (void *ptr, int len = sizeof (char));
- ssize_t recv_urg (void *ptr, int len = sizeof (char));
+ ssize_t send_n (const void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout = 0) const;
+ // Try to send exactly <len> bytes into <buf> from <handle>.
+
+ ssize_t send_n (const void *buf,
+ size_t len,
+ const ACE_Time_Value *timeout = 0) const;
+ // Try to send exactly <len> bytes into <buf> from <handle>.
+
+ ssize_t sendv_n (iovec iov[],
+ size_t iovcnt,
+ const ACE_Time_Value *timeout = 0) const;
+ // Send an <iovec> of size <iovcnt> to the connected socket.
+
+ // = Send/receive ``urgent'' data (see TCP specs...).
+ ssize_t send_urg (const void *ptr,
+ size_t len = sizeof (char),
+ const ACE_Time_Value *timeout = 0) const;
+
+ ssize_t recv_urg (void *ptr,
+ size_t len = sizeof (char),
+ const ACE_Time_Value *timeout = 0) const;
// = Selectively close endpoints.
int close_reader (void);
diff --git a/ace/SOCK_Stream.i b/ace/SOCK_Stream.i
index bef8d5c9c82..cb8b2d5f75e 100644
--- a/ace/SOCK_Stream.i
+++ b/ace/SOCK_Stream.i
@@ -47,91 +47,103 @@ ACE_SOCK_Stream::close_writer (void)
}
ASYS_INLINE ssize_t
-ACE_SOCK_Stream::send_n (const void *buf, size_t len, int flags,
- const ACE_Time_Value *timeout)
-{
- ACE_TRACE ("ACE_SOCK_Stream::send_n");
- return ACE::send_n (this->get_handle (), buf, len, flags, timeout);
-}
-
-ASYS_INLINE ssize_t
-ACE_SOCK_Stream::recv_n (void *buf, size_t len, int flags,
- const ACE_Time_Value *timeout)
+ACE_SOCK_Stream::recv_n (void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout) const
{
ACE_TRACE ("ACE_SOCK_Stream::recv_n");
- return ACE::recv_n (this->get_handle (), buf, len, flags, timeout);
+ return ACE::recv_n (this->get_handle (),
+ buf,
+ len,
+ flags,
+ timeout);
}
-// Receive exactly BUF_SIZE bytes from file descriptor this->handle
-// into <buf>. Keep trying until this many bytes are received.
-
ASYS_INLINE ssize_t
-ACE_SOCK_Stream::recv_n (void *buf, int buf_size, int flags) const
+ACE_SOCK_Stream::recv_n (void *buf,
+ size_t len,
+ const ACE_Time_Value *timeout) const
{
ACE_TRACE ("ACE_SOCK_Stream::recv_n");
- return ACE::recv_n (this->get_handle (), buf, buf_size, flags);
+ return ACE::recv_n (this->get_handle (),
+ buf,
+ len,
+ timeout);
}
-// Send exactly N bytes from <buf> to <handle>. Keeping trying
-// until this many bytes are sent.
-
ASYS_INLINE ssize_t
-ACE_SOCK_Stream::send_n (const void *buf, int buf_size, int flags) const
+ACE_SOCK_Stream::recvv_n (iovec iov[],
+ size_t n,
+ const ACE_Time_Value *timeout) const
{
- ACE_TRACE ("ACE_SOCK_Stream::send_n");
- return ACE::send_n (this->get_handle (), buf, buf_size, flags);
+ ACE_TRACE ("ACE_SOCK_Stream::recvv_n");
+ return ACE::recvv_n (this->get_handle (),
+ iov,
+ n,
+ timeout);
}
-// Receive exactly BUF_SIZE bytes from file descriptor
-// into BUF. Keep trying until this many bytes are received.
-
ASYS_INLINE ssize_t
-ACE_SOCK_Stream::recv_n (void *buf, int buf_size) const
+ACE_SOCK_Stream::send_n (const void *buf,
+ size_t len,
+ int flags,
+ const ACE_Time_Value *timeout) const
{
- ACE_TRACE ("ACE_SOCK_Stream::recv_n");
- return ACE::recv_n (this->get_handle (), buf, buf_size);
+ ACE_TRACE ("ACE_SOCK_Stream::send_n");
+ return ACE::send_n (this->get_handle (),
+ buf,
+ len,
+ flags,
+ timeout);
}
-// Send exactly N bytes from BUF to THIS->SOK_FD. Keeping trying
-// until this many bytes are sent.
-
ASYS_INLINE ssize_t
-ACE_SOCK_Stream::send_n (const void *buf, int buf_size) const
+ACE_SOCK_Stream::send_n (const void *buf,
+ size_t len,
+ const ACE_Time_Value *timeout) const
{
ACE_TRACE ("ACE_SOCK_Stream::send_n");
- return ACE::send_n (this->get_handle (), buf, buf_size);
+ return ACE::send_n (this->get_handle (),
+ buf,
+ len,
+ timeout);
}
ASYS_INLINE ssize_t
-ACE_SOCK_Stream::sendv_n (const iovec iov[], size_t n) const
+ACE_SOCK_Stream::sendv_n (iovec iov[],
+ size_t n,
+ const ACE_Time_Value *timeout) const
{
ACE_TRACE ("ACE_SOCK_Stream::sendv_n");
return ACE::sendv_n (this->get_handle (),
iov,
- n);
-}
-
-// Recv an n byte message from the connected socket.
-
-ASYS_INLINE ssize_t
-ACE_SOCK_Stream::recvv_n (iovec iov[], size_t n) const
-{
- ACE_TRACE ("ACE_SOCK_Stream::recvv_n");
- // @@ Carlos, can you please update this to call the
- // new ACE::recvv_n() method that you write?
- return ACE_OS::recvv (this->get_handle (), iov, n);
+ n,
+ timeout);
}
ASYS_INLINE ssize_t
-ACE_SOCK_Stream::send_urg (void *ptr, int len)
+ACE_SOCK_Stream::send_urg (const void *ptr,
+ size_t len,
+ const ACE_Time_Value *timeout) const
{
ACE_TRACE ("ACE_SOCK_Stream::send_urg");
- return ACE_OS::send (this->get_handle (), (char *) ptr, len, MSG_OOB);
+ return ACE::send (this->get_handle (),
+ ptr,
+ len,
+ MSG_OOB,
+ timeout);
}
ASYS_INLINE ssize_t
-ACE_SOCK_Stream::recv_urg (void *ptr, int len)
+ACE_SOCK_Stream::recv_urg (void *ptr,
+ size_t len,
+ const ACE_Time_Value *timeout) const
{
ACE_TRACE ("ACE_SOCK_Stream::recv_urg");
- return ACE_OS::recv (this->get_handle (), (char *) ptr, len, MSG_OOB);
+ return ACE::recv (this->get_handle (),
+ ptr,
+ len,
+ MSG_OOB,
+ timeout);
}
diff --git a/ace/config-win32-common.h b/ace/config-win32-common.h
index bf3993e0053..7f34486b674 100644
--- a/ace/config-win32-common.h
+++ b/ace/config-win32-common.h
@@ -14,6 +14,20 @@
// ---------------- platform features or lack of them -------------
+//
+// It seems like Win32 does not have a limit on the number of buffers
+// that can be transferred by the scatter/gather type of I/O
+// functions, e.g., WSASend and WSARecv. We are arbitrarily setting
+// this to be 1k for now. The typically use case is to create an I/O
+// vector array of size IOV_MAX on the stack and then filled in. Note
+// that we probably don't want too big a value for IOV_MAX since it
+// may mostly go to waste or the size of the activation record may
+// become excessively large.
+//
+# if !defined (IOV_MAX)
+# define IOV_MAX 1024
+# endif /* IOV_MAX */
+
#if !defined (ACE_HAS_WINCE)
// Platform supports pread() and pwrite()
#define ACE_HAS_P_READ_WRITE
@@ -400,11 +414,11 @@ typedef unsigned __int64 ACE_UINT64;
#include /**/ <winsock2.h>
#endif /* _WINSOCK2API */
- #if defined (ACE_HAS_FORE_ATM_WS2)
- #include /**/ <ws2atm.h>
- #endif /*ACE_HAS_FORE_ATM_WS2 */
+ #if defined (ACE_HAS_FORE_ATM_WS2)
+ #include /**/ <ws2atm.h>
+ #endif /*ACE_HAS_FORE_ATM_WS2 */
- #if !defined _MSWSOCK_
+ #if !defined _MSWSOCK_
#include /**/ <mswsock.h>
#endif /* _MSWSOCK_ */