#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 }
|
1.3.6