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


Public Methods | |
| ACE_WIN32_Asynch_Read_Stream (ACE_WIN32_Proactor *win32_proactor) | |
| Constructor. More... | |
| int | read (ACE_Message_Block &message_block, size_t bytes_to_read, const void *act, int priority, int signal_number=0) |
| This starts off an asynchronous read. Upto <bytes_to_read> will be read and stored in the <message_block>. More... | |
| 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. More... | |
| 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 | |
| int | shared_read (ACE_WIN32_Asynch_Read_Stream_Result *result) |
| This is the method which does the real work and is there so that the ACE_Asynch_Read_File class can use it too. More... | |
Once <open> is called, multiple asynchronous <read>s can started using this class. An ACE_Asynch_Read_Stream::Result will be passed back to the <handler> when the asynchronous reads completes through the <ACE_Handler::handle_read_stream> callback.
Definition at line 316 of file WIN32_Asynch_IO.h.
|
|
Constructor.
Definition at line 359 of file WIN32_Asynch_IO.cpp.
00360 : ACE_Asynch_Operation_Impl (), 00361 ACE_Asynch_Read_Stream_Impl (), 00362 ACE_WIN32_Asynch_Operation (win32_proactor) 00363 { 00364 } |
|
|
Destructor.
Definition at line 539 of file WIN32_Asynch_IO.cpp.
00540 {
00541 }
|
|
|
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 608 of file WIN32_Asynch_IO.cpp. References ACE_WIN32_Asynch_Operation::cancel.
00609 {
00610 return ACE_WIN32_Asynch_Operation::cancel ();
00611 }
|
|
||||||||||||||||||||
|
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. Reimplemented in ACE_WIN32_Asynch_Read_File. Definition at line 596 of file WIN32_Asynch_IO.cpp. References ACE_WIN32_Asynch_Operation::open.
00600 {
00601 return ACE_WIN32_Asynch_Operation::open (handler,
00602 handle,
00603 completion_key,
00604 proactor);
00605 }
|
|
|
Return the underlying proactor.
Reimplemented from ACE_WIN32_Asynch_Operation. Reimplemented in ACE_WIN32_Asynch_Read_File. Definition at line 614 of file WIN32_Asynch_IO.cpp. References ACE_WIN32_Asynch_Operation::proactor.
00615 {
00616 return ACE_WIN32_Asynch_Operation::proactor ();
00617 }
|
|
||||||||||||||||||||||||
|
This starts off an asynchronous read. Upto <bytes_to_read> will be read and stored in the <message_block>.
Implements ACE_Asynch_Read_Stream_Impl. Reimplemented in ACE_WIN32_Asynch_Read_File. Definition at line 367 of file WIN32_Asynch_IO.cpp. References ACE_NEW_RETURN, shared_read, ACE_Message_Block::space, and ssize_t. Referenced by ACE_WIN32_Asynch_Read_File::read.
00372 {
00373 size_t space = message_block.space ();
00374 if (bytes_to_read > space)
00375 bytes_to_read = space;
00376
00377 if (bytes_to_read == 0)
00378 {
00379 errno = ENOSPC;
00380 return -1;
00381 }
00382
00383 // Create the Asynch_Result.
00384 ACE_WIN32_Asynch_Read_Stream_Result *result = 0;
00385 ACE_NEW_RETURN (result,
00386 ACE_WIN32_Asynch_Read_Stream_Result (*this->handler_,
00387 this->handle_,
00388 message_block,
00389 bytes_to_read,
00390 act,
00391 this->win32_proactor_->get_handle (),
00392 priority,
00393 signal_number),
00394 -1);
00395
00396 // Shared read
00397 ssize_t return_val = this->shared_read (result);
00398
00399 // Upon errors
00400 if (return_val == -1)
00401 delete result;
00402
00403 return return_val;
00404 }
|
|
||||||||||||||||||||||||
|
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 407 of file WIN32_Asynch_IO.cpp. References ACE_ASSERT, ACE_DEBUG, ACE_ERROR_RETURN, ACE_IOV_MAX, ACE_LIB_TEXT, ACE_NEW_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.
00412 {
00413
00414 iovec iov[ACE_IOV_MAX];
00415 int iovcnt = 0;
00416
00417 // We should not read more than user requested,
00418 // but it is allowed to read less
00419
00420 for (const ACE_Message_Block* msg = &message_block;
00421 msg != 0 && bytes_to_read > 0 && iovcnt < ACE_IOV_MAX;
00422 msg = msg->cont () , ++iovcnt )
00423 {
00424 size_t msg_space = msg->space ();
00425
00426 // OS should correctly process zero length buffers
00427 // if ( msg_space == 0 )
00428 // ACE_ERROR_RETURN ((LM_ERROR,
00429 // ACE_LIB_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:")
00430 // ACE_LIB_TEXT ("No space in the message block\n")),
00431 // -1);
00432
00433 if (msg_space > bytes_to_read)
00434 msg_space = bytes_to_read;
00435 bytes_to_read -= msg_space;
00436
00437 // Make as many iovec as needed to fit all of msg_space.
00438 size_t wr_ptr_offset = 0;
00439 while (msg_space > 0 && iovcnt < ACE_IOV_MAX)
00440 {
00441 u_long this_chunk_length;
00442 if (msg_space > ULONG_MAX)
00443 this_chunk_length = ULONG_MAX;
00444 else
00445 this_chunk_length = ACE_static_cast (u_long, msg_space);
00446 // Collect the data in the iovec.
00447 iov[iovcnt].iov_base = msg->wr_ptr () + wr_ptr_offset;
00448 iov[iovcnt].iov_len = this_chunk_length;
00449 msg_space -= this_chunk_length;
00450 wr_ptr_offset += this_chunk_length;
00451
00452 // Increment iovec counter if there's more to do.
00453 if (msg_space > 0)
00454 iovcnt++;
00455 }
00456 if (msg_space > 0) // Ran out of iovecs before msg_space exhausted
00457 {
00458 errno = ERANGE;
00459 return -1;
00460 }
00461 }
00462
00463 // Re-calculate number bytes to read
00464 bytes_to_read = 0;
00465
00466 for (int i = 0; i < iovcnt ; ++i)
00467 bytes_to_read += iov[i].iov_len;
00468
00469 if (bytes_to_read == 0)
00470 ACE_ERROR_RETURN ((LM_ERROR,
00471 ACE_LIB_TEXT ("ACE_WIN32_Asynch_Read_Stream::readv:")
00472 ACE_LIB_TEXT ("Attempt to read 0 bytes\n")),
00473 -1);
00474
00475 // Create the Asynch_Result.
00476 ACE_WIN32_Asynch_Read_Stream_Result *result = 0;
00477 ACE_NEW_RETURN (result,
00478 ACE_WIN32_Asynch_Read_Stream_Result (*this->handler_,
00479 this->handle_,
00480 message_block,
00481 bytes_to_read,
00482 act,
00483 this->win32_proactor_->get_handle (),
00484 priority,
00485 signal_number,
00486 1), // scatter read enabled
00487 -1);
00488
00489 // do the scatter recv
00490
00491 result->set_error (0); // Clear error before starting IO.
00492
00493 DWORD bytes_recvd = 0;
00494 u_long flags = 0;
00495
00496 int initiate_result = ::WSARecv (ACE_reinterpret_cast (SOCKET, result->handle ()),
00497 ACE_reinterpret_cast (WSABUF *, iov),
00498 iovcnt,
00499 &bytes_recvd,
00500 &flags,
00501 result,
00502 0);
00503
00504 if (0 == initiate_result)
00505 // Immediate success: the OVERLAPPED will still get queued.
00506 return 1;
00507
00508 ACE_ASSERT (initiate_result == SOCKET_ERROR);
00509
00510 // If initiate failed, check for a bad error.
00511 ACE_OS::set_errno_to_last_error ();
00512 switch (errno)
00513 {
00514 case ERROR_IO_PENDING:
00515 // The IO will complete proactively: the OVERLAPPED will still
00516 // get queued.
00517 initiate_result = 0;
00518 break;
00519
00520 default:
00521 // Something else went wrong: the OVERLAPPED will not get
00522 // queued.
00523
00524 if (ACE::debug ())
00525 {
00526 ACE_DEBUG ((LM_ERROR,
00527 ACE_LIB_TEXT ("%p\n"),
00528 ACE_LIB_TEXT ("WSARecv")));
00529 }
00530
00531 delete result;
00532 initiate_result = -1;
00533 break;
00534 }
00535
00536 return initiate_result;
00537 }
|
|
|
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 544 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.
00545 {
00546 // ReadFile API limits us to DWORD range.
00547 if (result->bytes_to_read () > MAXDWORD)
00548 {
00549 errno = ERANGE;
00550 return -1;
00551 }
00552 DWORD bytes_to_read = ACE_static_cast (DWORD, result->bytes_to_read ());
00553 u_long bytes_read;
00554
00555 result->set_error (0); // Clear error before starting IO.
00556
00557 // Initiate the read
00558 int initiate_result = ::ReadFile (result->handle (),
00559 result->message_block ().wr_ptr (),
00560 bytes_to_read,
00561 &bytes_read,
00562 result);
00563 if (initiate_result == 1)
00564 // Immediate success: the OVERLAPPED will still get queued.
00565 return 1;
00566
00567 // If initiate failed, check for a bad error.
00568 ACE_OS::set_errno_to_last_error ();
00569 switch (errno)
00570 {
00571 case ERROR_IO_PENDING:
00572 // The IO will complete proactively: the OVERLAPPED will still
00573 // get queued.
00574 return 0;
00575
00576 default:
00577 // Something else went wrong: the OVERLAPPED will not get
00578 // queued.
00579
00580 if (ACE::debug ())
00581 {
00582 ACE_DEBUG ((LM_ERROR,
00583 ACE_LIB_TEXT ("%p\n"),
00584 ACE_LIB_TEXT ("ReadFile")));
00585 }
00586
00587 return -1;
00588 }
00589 }
|
1.2.14 written by Dimitri van Heesch,
© 1997-2002