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