#include <WIN32_Asynch_IO.h>
Inheritance diagram for ACE_WIN32_Asynch_Read_Dgram:


Public Methods | |
| ACE_WIN32_Asynch_Read_Dgram (ACE_WIN32_Proactor *win32_proactor) | |
| Constructor. More... | |
| virtual | ~ACE_WIN32_Asynch_Read_Dgram (void) |
| Destructor. More... | |
| virtual ssize_t | recv (ACE_Message_Block *message_block, size_t &number_of_bytes_recvd, int flags, int protocol_family, const void *act, int priority, int signal_number) |
| int | open (ACE_Handler &handler, ACE_HANDLE handle, const void *completion_key, ACE_Proactor *proactor) |
| int | cancel (void) |
| ACE_Proactor * | proactor (void) const |
| Return the underlying proactor. More... | |
Protected Methods | |
| ACE_WIN32_Asynch_Read_Dgram (void) | |
| Do-nothing constructor. More... | |
Once <open> is called, multiple asynchronous <read>s can be started using this class. An ACE_Asynch_Read_Dgram::Result will be passed back to the <handler> when the asynchronous reads completes through the <ACE_Handler::handle_read_stream> callback.
Definition at line 1692 of file WIN32_Asynch_IO.h.
|
|
Constructor.
Definition at line 3421 of file WIN32_Asynch_IO.cpp.
03422 : ACE_Asynch_Operation_Impl (), 03423 ACE_Asynch_Read_Dgram_Impl (), 03424 ACE_WIN32_Asynch_Operation (win32_proactor) 03425 { 03426 } |
|
|
Destructor.
Definition at line 3262 of file WIN32_Asynch_IO.cpp.
03263 {
03264 }
|
|
|
Do-nothing constructor.
|
|
|
This cancels all pending accepts operations that were issued by the calling thread. The function does not cancel asynchronous operations issued by other threads. Reimplemented from ACE_WIN32_Asynch_Operation. Definition at line 3410 of file WIN32_Asynch_IO.cpp. References ACE_WIN32_Asynch_Operation::cancel.
03411 {
03412 return ACE_WIN32_Asynch_Operation::cancel ();
03413 }
|
|
||||||||||||||||||||
|
Initializes the factory with information which will be used with each asynchronous call. If (<handle> == ACE_INVALID_HANDLE), <ACE_Handler::handle> will be called on the <handler> to get the correct handle. Reimplemented from ACE_WIN32_Asynch_Operation. Definition at line 3398 of file WIN32_Asynch_IO.cpp. References ACE_WIN32_Asynch_Operation::open.
03402 {
03403 return ACE_WIN32_Asynch_Operation::open (handler,
03404 handle,
03405 completion_key,
03406 proactor);
03407 }
|
|
|
Return the underlying proactor.
Reimplemented from ACE_WIN32_Asynch_Operation. Definition at line 3416 of file WIN32_Asynch_IO.cpp. References ACE_WIN32_Asynch_Operation::proactor.
03417 {
03418 return ACE_WIN32_Asynch_Operation::proactor ();
03419 }
|
|
||||||||||||||||||||||||||||||||
|
This starts off an asynchronous read. Upto <message_block->total_size()> will be read and stored in the <message_block>. <message_block>'s <wr_ptr> will be updated to reflect the added bytes if the read operation is successfully completed. Return code of 1 means immediate success and <number_of_bytes_recvd> will contain number of bytes read. The <ACE_Handler::handle_read_dgram> method will still be called. Return code of 0 means the IO will complete proactively. Return code of -1 means there was an error, use errno to get the error code. Scatter/gather is supported on WIN32 by using the <message_block->cont()> method. Up to ACE_IOV_MAX <message_block>'s are supported. Upto <message_block->size()> bytes will be read into each <message block> for a total of <message_block->total_size()> bytes. All <message_block>'s <wr_ptr>'s will be updated to reflect the added bytes for each <message_block> Implements ACE_Asynch_Read_Dgram_Impl. Definition at line 3267 of file WIN32_Asynch_IO.cpp. References ACE_DEBUG, ACE_ERROR_RETURN, ACE_IOV_MAX, ACE_LIB_TEXT, ACE_NEW_RETURN, ACE_WIN32_Asynch_Read_Dgram_Result::addr_len_, ACE_Message_Block::cont, ACE::debug, ACE_WIN32_Asynch_Read_Dgram_Result::flags_, ACE_WIN32_Asynch_Read_Dgram_Result::handle, iovec::iov_base, iovec::iov_len, LM_ERROR, ACE_OS::recvfrom, ACE_WIN32_Asynch_Read_Dgram_Result::saddr, ACE_OS::set_errno_to_last_error, ACE_Message_Block::space, and ACE_Message_Block::wr_ptr.
03274 {
03275 number_of_bytes_recvd = 0;
03276
03277 size_t bytes_to_read = 0;
03278
03279 iovec iov[ACE_IOV_MAX];
03280 int iovcnt = 0;
03281
03282 for (const ACE_Message_Block* msg = message_block;
03283 msg != 0 && iovcnt < ACE_IOV_MAX;
03284 msg = msg->cont () , ++iovcnt )
03285 {
03286 size_t msg_space = msg->space ();
03287
03288 // OS should correctly process zero length buffers
03289 // if ( msg_space == 0 )
03290 // ACE_ERROR_RETURN ((LM_ERROR,
03291 // ACE_LIB_TEXT ("ACE_WIN32_Asynch_Read_Dgram::recv:")
03292 // ACE_LIB_TEXT ("No space in the message block\n")),
03293 // -1);
03294
03295 bytes_to_read += msg_space;
03296
03297 // Make as many iovec as needed to fit all of msg_len.
03298 size_t wr_ptr_offset = 0;
03299 while (msg_space > 0 && iovcnt < ACE_IOV_MAX)
03300 {
03301 u_long this_chunk_length;
03302 if (msg_space > ULONG_MAX)
03303 this_chunk_length = ULONG_MAX;
03304 else
03305 this_chunk_length = ACE_static_cast (u_long, msg_space);
03306 // Collect the data in the iovec.
03307 iov[iovcnt].iov_base = msg->wr_ptr () + wr_ptr_offset;
03308 iov[iovcnt].iov_len = this_chunk_length;
03309 msg_space -= this_chunk_length;
03310 wr_ptr_offset += this_chunk_length;
03311
03312 // Increment iovec counter if there's more to do.
03313 if (msg_space > 0)
03314 iovcnt++;
03315 }
03316 if (msg_space > 0) // Ran out of iovecs before msg_space exhausted
03317 {
03318 errno = ERANGE;
03319 return -1;
03320 }
03321 }
03322
03323 if (bytes_to_read == 0)
03324 ACE_ERROR_RETURN ((LM_ERROR,
03325 ACE_LIB_TEXT ("ACE_WIN32_Asynch_Read_Dgram::recv:")
03326 ACE_LIB_TEXT ("Attempt to read 0 bytes\n")),
03327 -1);
03328
03329 // Create the Asynch_Result.
03330 ACE_WIN32_Asynch_Read_Dgram_Result *result = 0;
03331 ACE_NEW_RETURN (result,
03332 ACE_WIN32_Asynch_Read_Dgram_Result (*this->handler_,
03333 this->handle_,
03334 message_block,
03335 bytes_to_read,
03336 flags,
03337 protocol_family,
03338 act,
03339 this->win32_proactor_->get_handle (),
03340 priority,
03341 signal_number),
03342 -1);
03343
03344 // do the scatter/gather recv
03345 int initiate_result = ACE_OS::recvfrom (result->handle (),
03346 iov,
03347 iovcnt,
03348 number_of_bytes_recvd,
03349 result->flags_,
03350 result->saddr (),
03351 &(result->addr_len_),
03352 result,
03353 0);
03354 if (initiate_result == SOCKET_ERROR)
03355 {
03356 // If initiate failed, check for a bad error.
03357 ACE_OS::set_errno_to_last_error ();
03358 switch (errno)
03359 {
03360 case ERROR_IO_PENDING:
03361 // The IO will complete proactively: the OVERLAPPED will still
03362 // get queued.
03363 initiate_result = 0;
03364 break;
03365
03366 default:
03367 // Something else went wrong: the OVERLAPPED will not get
03368 // queued.
03369
03370 if (ACE::debug ())
03371 {
03372 ACE_DEBUG ((LM_ERROR,
03373 ACE_LIB_TEXT ("%p\n"),
03374 ACE_LIB_TEXT ("WSARecvFrom")));
03375 }
03376
03377 delete result;
03378 initiate_result = -1;
03379 break;
03380 }
03381
03382 }
03383 else
03384 {
03385 // Immediate success: the OVERLAPPED will still get queued.
03386 // number_of_bytes_recvd contains the number of bytes recvd
03387 // addr contains the peer address
03388 // flags was updated
03389
03390 // number_of_bytes_recvd = bytes_recvd;
03391 initiate_result = 1;
03392 }
03393
03394 return initiate_result;
03395 }
|
1.2.14 written by Dimitri van Heesch,
© 1997-2002