diff options
author | mcorino <mcorino@users.noreply.github.com> | 2014-11-03 13:02:06 +0000 |
---|---|---|
committer | mcorino <mcorino@users.noreply.github.com> | 2014-11-03 13:02:06 +0000 |
commit | 51d754127c5da94b529aaea795b339a2f7b860b0 (patch) | |
tree | 31ce96d183f515869b4d128d733c6466f17327e0 | |
parent | 15dffd77d9973d537285aa22daad528e7b350d65 (diff) | |
download | ATCD-51d754127c5da94b529aaea795b339a2f7b860b0.tar.gz |
ChangelogTag: Mon Nov 3 12:50:28 UTC 2014 Martin Corino <mcorino@remedy.nl>
-rw-r--r-- | ACE/ChangeLog | 10 | ||||
-rw-r--r-- | ACE/ace/WIN32_Asynch_IO.cpp | 3 | ||||
-rw-r--r-- | ACE/tests/Proactor_File_Test.cpp | 73 |
3 files changed, 79 insertions, 7 deletions
diff --git a/ACE/ChangeLog b/ACE/ChangeLog index d7617674628..36515e24eb4 100644 --- a/ACE/ChangeLog +++ b/ACE/ChangeLog @@ -1,3 +1,13 @@ +Mon Nov 3 12:50:28 UTC 2014 Martin Corino <mcorino@remedy.nl> + + * ace/WIN32_Asynch_IO.cpp: + Do not pass holder for bytes written when using OVERLAPPED IO. + Pass NULL instead. Recommended by MSDN. + + * tests/Proactor_File_Test.cpp: + Circumvent problems with unreliable Async IO on older Win32 + (WinXP, Win2003/2008). + Fri Oct 31 14:10:52 UTC 2014 Johnny Willemsen <jwillemsen@remedy.nl> * rpmbuild/ace-tao.spec: diff --git a/ACE/ace/WIN32_Asynch_IO.cpp b/ACE/ace/WIN32_Asynch_IO.cpp index 757329b4e99..2a6806a17f2 100644 --- a/ACE/ace/WIN32_Asynch_IO.cpp +++ b/ACE/ace/WIN32_Asynch_IO.cpp @@ -578,7 +578,6 @@ ACE_WIN32_Asynch_Read_Stream::shared_read (ACE_WIN32_Asynch_Read_Stream_Result * return -1; } DWORD bytes_to_read = static_cast<DWORD> (result->bytes_to_read ()); - u_long bytes_read; result->set_error (0); // Clear error before starting IO. @@ -586,7 +585,7 @@ ACE_WIN32_Asynch_Read_Stream::shared_read (ACE_WIN32_Asynch_Read_Stream_Result * int initiate_result = ::ReadFile (result->handle (), result->message_block ().wr_ptr (), bytes_to_read, - &bytes_read, + NULL, result); if (initiate_result == 1) // Immediate success: the OVERLAPPED will still get queued. diff --git a/ACE/tests/Proactor_File_Test.cpp b/ACE/tests/Proactor_File_Test.cpp index cb872ffc666..522e174dca4 100644 --- a/ACE/tests/Proactor_File_Test.cpp +++ b/ACE/tests/Proactor_File_Test.cpp @@ -49,6 +49,7 @@ class FileIOHandler : public ACE_Handler { public: + FileIOHandler (); virtual ~FileIOHandler (); int @@ -72,11 +73,23 @@ public: ACE_Asynch_Read_File reader_; ACE_Asynch_Write_File writer_; private: - int block_count_; + int block_count_; +#if defined (ACE_WIN32) + bool read_pending_; +#endif ACE_FILE_IO peer_; ACE_FILE_Connector connector_; }; +FileIOHandler::FileIOHandler () + : ACE_Handler () + , block_count_ (0) +#if defined (ACE_WIN32) + , read_pending_ (false) +#endif +{ +} + FileIOHandler::~FileIOHandler () { ACE_FILE_Addr tmp_addr; @@ -162,11 +175,27 @@ int FileIOHandler::Connect() ACE_NEW_NORETURN(mb, ACE_Message_Block(FILE_FRAME_SIZE)); if (reader_.read(*mb, mb->space()) != 0) { - ACE_ERROR( - (LM_ERROR, ACE_TEXT("%p\n"), ACE_TEXT("FileIOHandler begin read failed"))); + int errnr = ACE_OS::last_error (); + ACE_DEBUG( + (LM_INFO, ACE_TEXT("%p [%d]\n"), ACE_TEXT("FileIOHandler begin read failed"), errnr)); mb->release(); +#if defined (ACE_WIN32) + // On older Win32 versions (WinXP, Win2003/2008) asynch IO with disk files is not + // reliable and may perform sync IO in certain cases like when the read offset denotes + // current end of file. Instead of scheduling a write operation the read will immediately + // return with an EOF error. + // We circumvent that situation here by not reporting an error and scheduling a read operation + // later when we are sure data has been written at the offset in question (after the write finishes). + if (errnr != ERROR_HANDLE_EOF) +#endif result = -1; } +#if defined (ACE_WIN32) + else + { + this->read_pending_ = true; + } +#endif // If read worked, psMsg is now controlled by Proactor framework. } } @@ -217,8 +246,21 @@ FileIOHandler::handle_read_file(const ACE_Asynch_Read_File::Result &result) // Our processing is done; prime the read process again ACE_Message_Block *new_mb; ACE_NEW_NORETURN(new_mb, ACE_Message_Block(FILE_FRAME_SIZE)); - reader_.read(*new_mb, new_mb->space(), - result.offset () + result.bytes_transferred ()); + if (reader_.read(*new_mb, new_mb->space(), + result.offset () + result.bytes_transferred ()) != 0) + { + int errnr = ACE_OS::last_error (); + ACE_DEBUG( + (LM_INFO, ACE_TEXT("%p [%d]\n"), ACE_TEXT("FileIOHandler continuing read failed"), errnr)); + new_mb->release(); +#if defined (ACE_WIN32) + this->read_pending_ = false; + } + else + { + this->read_pending_ = true; +#endif + } } else { @@ -246,6 +288,27 @@ FileIOHandler::handle_write_file(const ACE_Asynch_Write_File::Result &result) // When the write completes, we get the message block. It's been sent, // so we just deallocate it. result.message_block().release(); +#if defined (ACE_WIN32) + // to circumvent problems on older Win32 (see above) we schedule a read here if none + // is pending yet. + if (!this->read_pending_) + { + ACE_Message_Block *mb; + ACE_NEW_NORETURN(mb, ACE_Message_Block(FILE_FRAME_SIZE)); + if (reader_.read(*mb, mb->space(), + (this->block_count_ - 1) * FILE_FRAME_SIZE) != 0) + { + int errnr = ACE_OS::last_error (); + ACE_DEBUG( + (LM_INFO, ACE_TEXT("%p [%d]\n"), ACE_TEXT("FileIOHandler read after write failed"), errnr)); + mb->release(); + } + else + { + this->read_pending_ = true; + } + } +#endif } //*************************************************************************** |