#include <WIN32_Asynch_IO.h>
Inheritance diagram for ACE_WIN32_Asynch_Read_Stream:
Public Member Functions | |
ACE_WIN32_Asynch_Read_Stream (ACE_WIN32_Proactor *win32_proactor) | |
Constructor. | |
int | read (ACE_Message_Block &message_block, size_t bytes_to_read, const void *act, int priority, int signal_number=0) |
int | readv (ACE_Message_Block &message_block, size_t bytes_to_read, const void *act, int priority, int signal_number=0) |
virtual | ~ACE_WIN32_Asynch_Read_Stream (void) |
Destructor. | |
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 | |
int | shared_read (ACE_WIN32_Asynch_Read_Stream_Result *result) |
Once is called, multiple asynchronous s can started using this class. An ACE_Asynch_Read_Stream::Result will be passed back to the when the asynchronous reads completes through the <ACE_Handler::handle_read_stream> callback.
Definition at line 318 of file WIN32_Asynch_IO.h.
|
Constructor.
Definition at line 378 of file WIN32_Asynch_IO.cpp.
00379 : ACE_Asynch_Operation_Impl (), 00380 ACE_Asynch_Read_Stream_Impl (), 00381 ACE_WIN32_Asynch_Operation (win32_proactor) 00382 { 00383 } |
|
Destructor.
Definition at line 566 of file WIN32_Asynch_IO.cpp.
00567 { 00568 } |
|
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. Reimplemented in ACE_WIN32_Asynch_Read_File. Definition at line 637 of file WIN32_Asynch_IO.cpp. References ACE_WIN32_Asynch_Operation::cancel().
00638 { 00639 return ACE_WIN32_Asynch_Operation::cancel (); 00640 } |
|
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. Reimplemented in ACE_WIN32_Asynch_Read_File. Definition at line 625 of file WIN32_Asynch_IO.cpp. References ACE_WIN32_Asynch_Operation::open(), and ACE_Handler::Proxy_Ptr.
00629 { 00630 return ACE_WIN32_Asynch_Operation::open (handler_proxy, 00631 handle, 00632 completion_key, 00633 proactor); 00634 } |
|
Return the underlying proactor.
Reimplemented from ACE_WIN32_Asynch_Operation. Reimplemented in ACE_WIN32_Asynch_Read_File. Definition at line 643 of file WIN32_Asynch_IO.cpp. References ACE_WIN32_Asynch_Operation::proactor().
00644 { 00645 return ACE_WIN32_Asynch_Operation::proactor (); 00646 } |
|
This starts off an asynchronous read. Upto will be read and stored in the . Implements ACE_Asynch_Read_Stream_Impl. Reimplemented in ACE_WIN32_Asynch_Read_File. Definition at line 386 of file WIN32_Asynch_IO.cpp. References ACE_NEW_RETURN, shared_read(), and ACE_Message_Block::space(). Referenced by ACE_WIN32_Asynch_Read_File::read().
00391 { 00392 size_t space = message_block.space (); 00393 if (bytes_to_read > space) 00394 bytes_to_read = space; 00395 00396 if (bytes_to_read == 0) 00397 { 00398 errno = ENOSPC; 00399 return -1; 00400 } 00401 00402 // Create the Asynch_Result. 00403 ACE_WIN32_Asynch_Read_Stream_Result *result = 0; 00404 ACE_NEW_RETURN (result, 00405 ACE_WIN32_Asynch_Read_Stream_Result (this->handler_proxy_, 00406 this->handle_, 00407 message_block, 00408 bytes_to_read, 00409 act, 00410 this->win32_proactor_->get_handle (), 00411 priority, 00412 signal_number), 00413 -1); 00414 00415 // Shared read 00416 int const return_val = this->shared_read (result); 00417 00418 // Upon errors 00419 if (return_val == -1) 00420 delete result; 00421 00422 return return_val; 00423 } |
|
Same as above but with scatter support, through chaining of composite message blocks using the continuation field. Implements ACE_Asynch_Read_Stream_Impl. Reimplemented in ACE_WIN32_Asynch_Read_File. Definition at line 426 of file WIN32_Asynch_IO.cpp. References ACE_ASSERT, ACE_DEBUG, ACE_ERROR_RETURN, ACE_IOV_MAX, ACE_LIB_TEXT, ACE_NEW_RETURN, ACE_NOTSUP_RETURN, ACE_Message_Block::cont(), ACE::debug(), ACE_WIN32_Asynch_Read_Stream_Result::handle(), iovec::iov_base, iovec::iov_len, LM_ERROR, ACE_OS::set_errno_to_last_error(), ACE_WIN32_Asynch_Result::set_error(), ACE_Message_Block::space(), and ACE_Message_Block::wr_ptr(). Referenced by ACE_WIN32_Asynch_Read_File::readv().
00431 { 00432 #if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) 00433 iovec iov[ACE_IOV_MAX]; 00434 int iovcnt = 0; 00435 00436 // We should not read more than user requested, 00437 // but it is allowed to read less 00438 00439 for (const ACE_Message_Block* msg = &message_block; 00440 msg != 0 && bytes_to_read > 0 && iovcnt < ACE_IOV_MAX; 00441 msg = msg->cont () , ++iovcnt ) 00442 { 00443 size_t msg_space = msg->space (); 00444 00445 // OS should correctly process zero length buffers 00446 // if ( msg_space == 0 ) 00447 // ACE_ERROR_RETURN ((LM_ERROR, 00448 // ACE_LIB_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:") 00449 // ACE_LIB_TEXT ("No space in the message block\n")), 00450 // -1); 00451 00452 if (msg_space > bytes_to_read) 00453 msg_space = bytes_to_read; 00454 bytes_to_read -= msg_space; 00455 00456 // Make as many iovec as needed to fit all of msg_space. 00457 size_t wr_ptr_offset = 0; 00458 while (msg_space > 0 && iovcnt < ACE_IOV_MAX) 00459 { 00460 u_long this_chunk_length; 00461 if (msg_space > ULONG_MAX) 00462 this_chunk_length = ULONG_MAX; 00463 else 00464 this_chunk_length = static_cast<u_long> (msg_space); 00465 // Collect the data in the iovec. 00466 iov[iovcnt].iov_base = msg->wr_ptr () + wr_ptr_offset; 00467 iov[iovcnt].iov_len = this_chunk_length; 00468 msg_space -= this_chunk_length; 00469 wr_ptr_offset += this_chunk_length; 00470 00471 // Increment iovec counter if there's more to do. 00472 if (msg_space > 0) 00473 ++iovcnt; 00474 } 00475 if (msg_space > 0) // Ran out of iovecs before msg_space exhausted 00476 { 00477 errno = ERANGE; 00478 return -1; 00479 } 00480 } 00481 00482 // Re-calculate number bytes to read 00483 bytes_to_read = 0; 00484 00485 for (int i = 0; i < iovcnt ; ++i) 00486 bytes_to_read += iov[i].iov_len; 00487 00488 if (bytes_to_read == 0) 00489 ACE_ERROR_RETURN ((LM_ERROR, 00490 ACE_LIB_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:") 00491 ACE_LIB_TEXT ("Attempt to read 0 bytes\n")), 00492 -1); 00493 00494 // Create the Asynch_Result. 00495 ACE_WIN32_Asynch_Read_Stream_Result *result = 0; 00496 ACE_NEW_RETURN (result, 00497 ACE_WIN32_Asynch_Read_Stream_Result (this->handler_proxy_, 00498 this->handle_, 00499 message_block, 00500 bytes_to_read, 00501 act, 00502 this->win32_proactor_->get_handle (), 00503 priority, 00504 signal_number, 00505 1), // scatter read enabled 00506 -1); 00507 00508 // do the scatter recv 00509 00510 result->set_error (0); // Clear error before starting IO. 00511 00512 DWORD bytes_recvd = 0; 00513 u_long flags = 0; 00514 00515 int initiate_result = ::WSARecv (reinterpret_cast<SOCKET> (result->handle ()), 00516 reinterpret_cast<WSABUF *> (iov), 00517 iovcnt, 00518 &bytes_recvd, 00519 &flags, 00520 result, 00521 0); 00522 00523 if (0 == initiate_result) 00524 // Immediate success: the OVERLAPPED will still get queued. 00525 return 1; 00526 00527 ACE_ASSERT (initiate_result == SOCKET_ERROR); 00528 00529 // If initiate failed, check for a bad error. 00530 ACE_OS::set_errno_to_last_error (); 00531 switch (errno) 00532 { 00533 case ERROR_IO_PENDING: 00534 // The IO will complete proactively: the OVERLAPPED will still 00535 // get queued. 00536 initiate_result = 0; 00537 break; 00538 00539 default: 00540 // Something else went wrong: the OVERLAPPED will not get 00541 // queued. 00542 00543 if (ACE::debug ()) 00544 { 00545 ACE_DEBUG ((LM_ERROR, 00546 ACE_LIB_TEXT ("%p\n"), 00547 ACE_LIB_TEXT ("WSARecv"))); 00548 } 00549 00550 delete result; 00551 initiate_result = -1; 00552 break; 00553 } 00554 00555 return initiate_result; 00556 #else 00557 ACE_UNUSED_ARG (message_block); 00558 ACE_UNUSED_ARG (bytes_to_read); 00559 ACE_UNUSED_ARG (act); 00560 ACE_UNUSED_ARG (priority); 00561 ACE_UNUSED_ARG (signal_number); 00562 ACE_NOTSUP_RETURN (-1); 00563 #endif /* ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2 != 0 */ 00564 } |
|
This is the method which does the real work and is there so that the ACE_Asynch_Read_File class can use it too. Definition at line 571 of file WIN32_Asynch_IO.cpp. References ACE_DEBUG, ACE_LIB_TEXT, ACE_WIN32_Asynch_Read_Stream_Result::bytes_to_read(), ACE::debug(), ACE_WIN32_Asynch_Read_Stream_Result::handle(), LM_ERROR, ACE_WIN32_Asynch_Read_Stream_Result::message_block(), ACE_OS::set_errno_to_last_error(), ACE_WIN32_Asynch_Result::set_error(), and ACE_Message_Block::wr_ptr(). Referenced by ACE_WIN32_Asynch_Read_File::read(), and read().
00572 { 00573 // ReadFile API limits us to DWORD range. 00574 if (result->bytes_to_read () > MAXDWORD) 00575 { 00576 errno = ERANGE; 00577 return -1; 00578 } 00579 DWORD bytes_to_read = static_cast<DWORD> (result->bytes_to_read ()); 00580 u_long bytes_read; 00581 00582 result->set_error (0); // Clear error before starting IO. 00583 00584 // Initiate the read 00585 int initiate_result = ::ReadFile (result->handle (), 00586 result->message_block ().wr_ptr (), 00587 bytes_to_read, 00588 &bytes_read, 00589 result); 00590 if (initiate_result == 1) 00591 // Immediate success: the OVERLAPPED will still get queued. 00592 return 0; 00593 00594 // If initiate failed, check for a bad error. 00595 ACE_OS::set_errno_to_last_error (); 00596 switch (errno) 00597 { 00598 case ERROR_IO_PENDING: 00599 /* FALLTHRU */ 00600 case ERROR_MORE_DATA: 00601 // The IO will complete proactively: the OVERLAPPED will still 00602 // get queued. 00603 return 0; 00604 00605 default: 00606 // Something else went wrong: the OVERLAPPED will not get 00607 // queued. 00608 00609 if (ACE::debug ()) 00610 { 00611 ACE_DEBUG ((LM_ERROR, 00612 ACE_LIB_TEXT ("%p\n"), 00613 ACE_LIB_TEXT ("ReadFile"))); 00614 } 00615 00616 return -1; 00617 } 00618 } |