POSIX_CB_Proactor.cpp

Go to the documentation of this file.
00001 // POSIX_CB_Proactor.cpp,v 4.19 2005/12/22 01:17:51 shuston Exp
00002 
00003 #include "ace/POSIX_CB_Proactor.h"
00004 
00005 #if defined (ACE_HAS_AIO_CALLS) && !defined(__Lynx__) && !defined (__FreeBSD__)
00006 
00007 #include "ace/Task_T.h"
00008 #include "ace/Log_Msg.h"
00009 #include "ace/Object_Manager.h"
00010 #include "ace/OS_NS_sys_time.h"
00011 
00012 ACE_RCSID (ace,
00013            POSIX_CB_Proactor,
00014            "POSIX_CB_Proactor.cpp,v 4.19 2005/12/22 01:17:51 shuston Exp")
00015 
00016 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00017 
00018 ACE_POSIX_CB_Proactor::ACE_POSIX_CB_Proactor (size_t max_aio_operations)
00019   : ACE_POSIX_AIOCB_Proactor (max_aio_operations,
00020                               ACE_POSIX_Proactor::PROACTOR_CB),
00021     sema_ ((unsigned int) 0)
00022 {
00023   // we should start pseudo-asynchronous accept task
00024   // one per all future acceptors
00025 
00026   this->get_asynch_pseudo_task ().start ();
00027 }
00028 
00029 // Destructor.
00030 ACE_POSIX_CB_Proactor::~ACE_POSIX_CB_Proactor (void)
00031 {
00032   this->close ();
00033 }
00034 
00035 ACE_POSIX_Proactor::Proactor_Type
00036 ACE_POSIX_CB_Proactor::get_impl_type (void)
00037 {
00038   return PROACTOR_CB;
00039 }
00040 
00041 void ACE_POSIX_CB_Proactor::aio_completion_func (sigval_t cb_data)
00042 {
00043   ACE_POSIX_CB_Proactor * impl = static_cast<ACE_POSIX_CB_Proactor *> (cb_data.sival_ptr);
00044   if ( impl != 0 )
00045     impl->notify_completion (0);
00046 }
00047 
00048 #if defined (ACE_HAS_SIG_C_FUNC)
00049 extern "C" void
00050 ACE_POSIX_CB_Proactor_aio_completion (sigval_t cb_data)
00051 {
00052   ACE_POSIX_CB_Proactor::aio_completion_func (cb_data);
00053 }
00054 #endif /* ACE_HAS_SIG_C_FUNC */
00055 
00056 int
00057 ACE_POSIX_CB_Proactor::handle_events (ACE_Time_Value &wait_time)
00058 {
00059   // Decrement <wait_time> with the amount of time spent in the method
00060   ACE_Countdown_Time countdown (&wait_time);
00061   return this->handle_events_i (wait_time.msec ());
00062 }
00063 
00064 int
00065 ACE_POSIX_CB_Proactor::handle_events (void)
00066 {
00067   return this->handle_events_i (ACE_INFINITE);
00068 }
00069 
00070 int
00071 ACE_POSIX_CB_Proactor::notify_completion (int sig_num)
00072 {
00073   ACE_UNUSED_ARG (sig_num);
00074 
00075   return this->sema_.release();
00076 }
00077 
00078 
00079 ssize_t
00080 ACE_POSIX_CB_Proactor::allocate_aio_slot (ACE_POSIX_Asynch_Result *result)
00081 {
00082   ssize_t slot = ACE_POSIX_AIOCB_Proactor::allocate_aio_slot (result);
00083   if (slot == -1)
00084     return -1;
00085 
00086   // setup OS notification methods for this aio
00087   // @@ TODO: This gets the completion method back to this proactor to
00088   // find the completed aiocb. It would be so much better to not only get
00089   // the proactor, but the aiocb as well.
00090 #if defined(__sgi)
00091   result->aio_sigevent.sigev_notify = SIGEV_CALLBACK;
00092   result->aio_sigevent.sigev_func   = aio_completion_func ;
00093 #else
00094   result->aio_sigevent.sigev_notify = SIGEV_THREAD;
00095 #  if defined (ACE_HAS_SIG_C_FUNC)
00096   result->aio_sigevent.sigev_notify_function =
00097     ACE_POSIX_CB_Proactor_aio_completion;
00098 #  else
00099   result->aio_sigevent.sigev_notify_function = aio_completion_func;
00100 #  endif /* ACE_HAS_SIG_C_FUNC */
00101   result->aio_sigevent.sigev_notify_attributes = 0;
00102 #endif /* __sgi */
00103 
00104   result->aio_sigevent.sigev_value.sival_ptr = this ;
00105 
00106   return slot;
00107 }
00108 
00109 int
00110 ACE_POSIX_CB_Proactor::handle_events_i (u_long milli_seconds)
00111 {
00112 
00113   int result_wait=0;
00114 
00115   // Wait for the signals.
00116   if (milli_seconds == ACE_INFINITE)
00117     {
00118       result_wait = this->sema_.acquire();
00119     }
00120   else
00121     {
00122       // Wait for <milli_seconds> amount of time.
00123       ACE_Time_Value abs_time = ACE_OS::gettimeofday ()
00124                               + ACE_Time_Value (0, milli_seconds * 1000);
00125 
00126       result_wait = this->sema_.acquire(abs_time);
00127     }
00128 
00129   // Check for errors
00130   // but let continue work in case of errors
00131   // we should check "post_completed" queue
00132   if (result_wait == -1)
00133     {
00134       if (errno != ETIME &&   // timeout
00135           errno != EINTR )    // interrupted system call
00136         ACE_ERROR ((LM_ERROR,
00137                     "%N:%l:(%P | %t)::%p\n",
00138                     "ACE_POSIX_CB_Proactor::handle_events:"
00139                     "semaphore acquire failed"
00140                   ));
00141     }
00142 
00143   size_t index = 0;          // start index to scan aiocb list
00144   size_t count = this->aiocb_list_max_size_;  // max number to iterate
00145 
00146   int error_status = 0;
00147   size_t return_status = 0;
00148 
00149   int ret_aio = 0;
00150   int ret_que = 0;
00151 
00152   for (;; ret_aio++)
00153     {
00154       ACE_POSIX_Asynch_Result * asynch_result =
00155           this->find_completed_aio (error_status,
00156                                     return_status,
00157                                     index,
00158                                     count);
00159 
00160       if (asynch_result == 0)
00161           break;
00162 
00163       // Call the application code.
00164       this->application_specific_code (asynch_result,
00165                                        return_status, // Bytes transferred.
00166                                        0,             // No completion key.
00167                                        error_status); // Error
00168      }
00169 
00170   // process post_completed results
00171   ret_que = this->process_result_queue ();
00172 
00173   // Uncomment this  if you want to test
00174   // and research the behavior of you system
00175   // ACE_DEBUG ((LM_DEBUG,
00176   //            "(%t) NumAIO=%d NumQueue=%d\n",
00177   //             ret_aio, ret_que));
00178 
00179   return ret_aio + ret_que > 0 ? 1 : 0;
00180 }
00181 
00182 ACE_END_VERSIONED_NAMESPACE_DECL
00183 
00184 #endif /* ACE_HAS_AIO_CALLS && !__Lynx__ && !__FreeBSD__ */

Generated on Thu Nov 9 09:41:59 2006 for ACE by doxygen 1.3.6