00001
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
00024
00025
00026 this->get_asynch_pseudo_task ().start ();
00027 }
00028
00029
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
00055
00056 int
00057 ACE_POSIX_CB_Proactor::handle_events (ACE_Time_Value &wait_time)
00058 {
00059
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
00087
00088
00089
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
00101 result->aio_sigevent.sigev_notify_attributes = 0;
00102 #endif
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
00116 if (milli_seconds == ACE_INFINITE)
00117 {
00118 result_wait = this->sema_.acquire();
00119 }
00120 else
00121 {
00122
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
00130
00131
00132 if (result_wait == -1)
00133 {
00134 if (errno != ETIME &&
00135 errno != EINTR )
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;
00144 size_t count = this->aiocb_list_max_size_;
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
00164 this->application_specific_code (asynch_result,
00165 return_status,
00166 0,
00167 error_status);
00168 }
00169
00170
00171 ret_que = this->process_result_queue ();
00172
00173
00174
00175
00176
00177
00178
00179 return ret_aio + ret_que > 0 ? 1 : 0;
00180 }
00181
00182 ACE_END_VERSIONED_NAMESPACE_DECL
00183
00184 #endif