diff options
author | alex <alex@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-06-20 04:53:02 +0000 |
---|---|---|
committer | alex <alex@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-06-20 04:53:02 +0000 |
commit | 26c64d921c76a4833a698b147bdb34c84b8a8900 (patch) | |
tree | caa9d1df2c3f4ef782bffa7810f0c968eef7c627 /ace/POSIX_Proactor.cpp | |
parent | b157bc621706d2049876cd60387287046f020733 (diff) | |
download | ATCD-26c64d921c76a4833a698b147bdb34c84b8a8900.tar.gz |
Incorporated Alex Libman <Alibman@baltimore.com> suggestions.
- MT safe'ing AIOCB proactor. It does not improve efficiency though.
- Enabling the completion call backs even if aio_return fails. We will
call the completion call back methods with 0 transferred data
parameter.
Thanks Alex for the great inputs!.
Diffstat (limited to 'ace/POSIX_Proactor.cpp')
-rw-r--r-- | ace/POSIX_Proactor.cpp | 198 |
1 files changed, 122 insertions, 76 deletions
diff --git a/ace/POSIX_Proactor.cpp b/ace/POSIX_Proactor.cpp index 123f4f9a6fe..01d10f8f3fe 100644 --- a/ace/POSIX_Proactor.cpp +++ b/ace/POSIX_Proactor.cpp @@ -637,87 +637,101 @@ ACE_POSIX_AIOCB_Proactor::handle_events (unsigned long milli_seconds) if (errno == EAGAIN) return 0; else - ACE_ERROR_RETURN ((LM_ERROR, - "%N:%l:(%P | %t)::%p\n", - "ACE_POSIX_AIOCB_Proactor::handle_events:" - "aio_suspend failed"), - -1); - } - - // No errors, check which aio has finished. - size_t ai; - int error_status = 0; - int return_status = 0; - for (ai = 0; ai < this->aiocb_list_max_size_; ai++) - { - // Dont process null blocks. - if (aiocb_list_ [ai] == 0) - continue; - - // Analyze error and return values. - - // Get the error status of the aio_ operation. - error_status = aio_error (aiocb_list_[ai]); - if (error_status == -1) - // <aio_error> itself has failed. - ACE_ERROR_RETURN ((LM_ERROR, - "%N:%l:(%P | %t)::%p\n", - "ACE_POSIX_AIOCB_Proactor::handle_events:" - "<aio_error> has failed"), - -1); - - // Continue the loop if <aio_> operation is still in progress. - if (error_status == EINPROGRESS) - continue; - - // Handle cancel'ed asynchronous operation. We dont have to call - // <aio_return> in this case, since return_status is going to be - // -1. We will pass 0 for the <bytes_transferred> in this case - if (error_status == ECANCELED) { - return_status = 0; - break; + ACE_DEBUG ((LM_ERROR, + "%N:%l:(%P | %t)::%p\n", + "ACE_POSIX_AIOCB_Proactor::handle_events:" + "aio_suspend failed")); + + return 0; } - - // Error_status is not -1 and not EINPROGRESS. So, an <aio_> - // operation has finished (successfully or unsuccessfully!!!) - // Get the return_status of the <aio_> operation. - return_status = aio_return (aiocb_list_[ai]); - - if (return_status == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%N:%l:(%P | %t)::%p\n", - "ACE_POSIX_AIOCB_Proactor::handle_events:" - "<aio_return> failed"), - -1); - else - // This AIO has finished. - break; } - // Something should have completed. - ACE_ASSERT (ai != this->aiocb_list_max_size_); - // Retrive the result pointer. - ACE_POSIX_Asynch_Result *asynch_result = this->result_list_ [ai]; - - // ACE_reinterpret_cast (ACE_POSIX_Asynch_Result *, - // this->aiocb_list_[ai]); - // ACE_dynamic_cast (ACE_POSIX_Asynch_Result *, - // this->aiocb_list_[ai]); - - // Invalidate entry in the aiocb list. - this->aiocb_list_[ai] = 0; - this->result_list_ [ai] = 0; - this->aiocb_list_cur_size_--; + ACE_POSIX_Asynch_Result *asynch_result = 0; + size_t ai; + int error_status = 0; + int return_status = 0; + // !!! Protected area. + { + ACE_Guard<ACE_Thread_Mutex> locker (this->mtx_AIOCB_); + + for (ai = 0; ai < this->aiocb_list_max_size_; ai++) + { + // Dont process null blocks. + if (aiocb_list_ [ai] == 0) + continue; + + // = Analyze error and return values. + + // Get the error status of the aio_ operation. + error_status = aio_error (aiocb_list_[ai]); + if (error_status == -1) + // <aio_error> itself has failed. + ACE_ERROR_RETURN ((LM_ERROR, + "%N:%l:(%P | %t)::%p\n", + "ACE_POSIX_AIOCB_Proactor::handle_events:" + "<aio_error> has failed"), + -1); + + // Continue the loop if <aio_> operation is still in progress. + if (error_status == EINPROGRESS) + continue; + + // Handle cancel'ed asynchronous operation. We dont have to call + // <aio_return> in this case, since return_status is going to be + // -1. We will pass 0 for the <bytes_transferred> in this case + if (error_status == ECANCELED) + { + return_status = 0; + break; + } + else if (error_status == 0) + { + // Error_status is not -1 and not EINPROGRESS. So, an <aio_> + // operation has finished (successfully or unsuccessfully!!!) + // Get the return_status of the <aio_> operation. + return_status = aio_return (aiocb_list_[ai]); + + if (return_status == -1) + { + ACE_DEBUG ((LM_ERROR, + "%N:%l:(%P | %t)::%p\n", + "ACE_POSIX_AIOCB_Proactor::handle_events:" + "<aio_return> failed to transfer any data\n")); + + return_status = 0; + } + + break; + } + } + + // Something should have completed. + ACE_ASSERT (ai != this->aiocb_list_max_size_); + + // Retrive the result pointer. + asynch_result = this->result_list_ [ai]; + + // ACE_reinterpret_cast (ACE_POSIX_Asynch_Result *, + // this->aiocb_list_[ai]); + // ACE_dynamic_cast (ACE_POSIX_Asynch_Result *, + // this->aiocb_list_[ai]); + + // Invalidate entry in the aiocb list. + this->aiocb_list_[ai] = 0; + this->result_list_ [ai] = 0; + this->aiocb_list_cur_size_--; + } // !! End of protected area. + // Call the application code. this->application_specific_code (asynch_result, return_status, // Bytes transferred. 1, // Success 0, // No completion key. error_status); // Error - + // Success return 1; } @@ -737,10 +751,15 @@ ACE_POSIX_AIOCB_Proactor::application_specific_code (ACE_POSIX_Asynch_Result *as } int -ACE_POSIX_AIOCB_Proactor::register_aio_with_proactor (ACE_POSIX_Asynch_Result *result) +ACE_POSIX_AIOCB_Proactor::register_aio_with_proactor (ACE_POSIX_Asynch_Result *result, int operation) { ACE_TRACE ("ACE_POSIX_AIOCB_Proactor::register_aio_with_proactor"); + // Protect the atomic action , which is: find free slot , start IO , + // save ptr in the lists + + ACE_Guard<ACE_Thread_Mutex> locker (this->mtx_AIOCB_); + if (result == 0) { // Just check the status of the list. @@ -774,6 +793,30 @@ ACE_POSIX_AIOCB_Proactor::register_aio_with_proactor (ACE_POSIX_Asynch_Result *r "Error:Asynch_Operation: No space to store the <aio> info.\n"), -1); + // Start the IO. + if (operation == 0) + { + // Read + if (aio_read (result) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Error:%p\n", + "Asynch_Read_XXXX: aio_read queueing failed\n"), + -1); + } + } + else + { + // write + if (aio_write (result) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Error:%p\n", + "Asynch_Read_XXXX: aio_read queueing failed\n"), + -1); + } + } + // Store the pointers. this->aiocb_list_[ai] = result; this->result_list_ [ai] = result; @@ -1177,13 +1220,16 @@ ACE_POSIX_SIG_Proactor::handle_events (unsigned long milli_seconds) // Failure. if (return_status == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%N:%l:(%P | %t)::%p\n", - "ACE_POSIX_SIG_Proactor::handle_events:" - "<aio_return> failed"), - -1); + { + ACE_DEBUG ((LM_ERROR, + "%N:%l:(%P | %t)::%p\n", + "ACE_POSIX_SIG_Proactor::handle_events:" + "<aio_return> failed to transfer any data\n")); + + return_status = 0; + } } - + // error status and return status are obtained. Dispatch the // completion . this->application_specific_code (asynch_result, |