summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ace/Asynch_IO.cpp17
-rw-r--r--ace/Asynch_IO.h8
-rw-r--r--ace/Proactor.cpp168
-rw-r--r--ace/Proactor.h130
4 files changed, 185 insertions, 138 deletions
diff --git a/ace/Asynch_IO.cpp b/ace/Asynch_IO.cpp
index a350e4ce366..18d2925fb01 100644
--- a/ace/Asynch_IO.cpp
+++ b/ace/Asynch_IO.cpp
@@ -89,8 +89,6 @@ ACE_Asynch_Result::event (void) const
return this->hEvent;
}
-// ************************************************************
-
ACE_Asynch_Operation::ACE_Asynch_Operation (void)
: handler_ (0),
handle_ (ACE_INVALID_HANDLE)
@@ -128,7 +126,8 @@ ACE_Asynch_Operation::open (ACE_Handler &handler,
#if !defined (ACE_HAS_AIO_CALLS)
// Register with the <proactor>
- return this->proactor_->register_handle (this->handle_, completion_key);
+ return this->proactor_->register_handle (this->handle_,
+ completion_key);
#else /* ACE_HAS_AIO_CALLS */
// AIO stuff is present. So no registering business.
return 1;
@@ -144,6 +143,8 @@ ACE_Asynch_Operation::cancel (void)
#if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) && (defined (_MSC_VER) && (_MSC_VER > 1020))
return (int) ::CancelIo (this->handle_);
#else
+ // @@ Alex, there should be an API for cancelling this stuff on
+ // POSIX!
ACE_NOTSUP_RETURN (-1);
#endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) && (defined (_MSC_VER) && (_MSC_VER > 1020)) */
}
@@ -179,9 +180,11 @@ ACE_Asynch_Read_Stream::shared_read (ACE_Asynch_Read_Stream::Result *result)
#if defined (ACE_HAS_AIO_CALLS)
// Make a new AIOCB and issue aio_read, if queueing is possible
// store this with the Proactor, so that that can be used for
- // aio_return6 and aio_error.
+ // <aio_return> and <aio_error>.
aiocb *aiocb_ptr;
- ACE_NEW_RETURN (aiocb_ptr, aiocb, -1);
+ ACE_NEW_RETURN (aiocb_ptr,
+ aiocb,
+ -1);
// Setup AIOCB.
// @@ Priority always 0?
@@ -196,7 +199,9 @@ ACE_Asynch_Read_Stream::shared_read (ACE_Asynch_Read_Stream::Result *result)
aiocb_ptr->aio_sigevent.sigev_value.sival_ptr =
(void *) aiocb_ptr;
- // Fire off the aio write.
+ // Fire off the aio write. @@ Alex, should this be < 0 or -1? In
+ // general, please try to use -1 for checking all return values if
+ // that's what the manual says will be returned...
if (aio_read (aiocb_ptr) < 0)
// Queuing failed.
ACE_ERROR_RETURN ((LM_ERROR,
diff --git a/ace/Asynch_IO.h b/ace/Asynch_IO.h
index ba9f8370e04..ba8c151dca8 100644
--- a/ace/Asynch_IO.h
+++ b/ace/Asynch_IO.h
@@ -10,15 +10,17 @@
// Asynch_IO.h
//
// = DESCRIPTION
-// This only works on Win32 platforms.
+// This only works on Win32 platforms or on POSIX platforms with
+// aio_ routines.
//
// The implementation of <ACE_Asynch_Transmit_File> and
// <ACE_Asynch_Accept> are only supported if ACE_HAS_WINSOCK2 is
// defined or you are on WinNT 4.0 or higher
//
// = AUTHOR
-// Irfan Pyarali (irfan@cs.wustl.edu)
-// Tim Harrison (harrison@cs.wustl.edu)
+// Irfan Pyarali (irfan@cs.wustl.edu),
+// Tim Harrison (harrison@cs.wustl.edu), and
+// Alexander Babu Arulanthu <alex@cs.wustl.edu>
//
// ============================================================================
diff --git a/ace/Proactor.cpp b/ace/Proactor.cpp
index 52553a5a6f8..1c05308bbef 100644
--- a/ace/Proactor.cpp
+++ b/ace/Proactor.cpp
@@ -1,5 +1,4 @@
-// Proactor.cpp
-// $Id: Proactor.cpp,v
+// $Id$
#define ACE_BUILD_DLL
#include "ace/Proactor.h"
@@ -28,22 +27,17 @@ int ACE_Proactor::delete_proactor_ = 0;
sig_atomic_t ACE_Proactor::end_event_loop_ = 0;
class ACE_Export ACE_Proactor_Timer_Handler : public ACE_Task <ACE_NULL_SYNCH>
- //
// = TITLE
- //
// A Handler for timer. It helps in the management of timers
// registered with the Proactor.
//
// = DESCRIPTION
- //
- // This object has a thread that will wait on the earliest
- // time in a list of timers and an event. When a timer
- // expires, the thread will post a completion event on the
- // port and go back to waiting on the timer queue and
- // event. If the event is signaled, the thread will refresh
- // the time it is currently waiting on (in case the earliest
- // time has changed)
- //
+ // This object has a thread that will wait on the earliest time
+ // in a list of timers and an event. When a timer expires, the
+ // thread will post a completion event on the port and go back
+ // to waiting on the timer queue and event. If the event is
+ // signaled, the thread will refresh the time it is currently
+ // waiting on (in case the earliest time has changed)
{
friend class ACE_Proactor;
// Proactor has special privileges
@@ -59,14 +53,14 @@ public:
protected:
virtual int svc (void);
// Run by a daemon thread to handle deferred processing. In other
- // words, this method will do the waiting on the earliest timer
- // and event
+ // words, this method will do the waiting on the earliest timer and
+ // event.
ACE_Auto_Event timer_event_;
- // Event to wait on
+ // Event to wait on.
ACE_Proactor &proactor_;
- // Proactor
+ // Proactor.
int shutting_down_;
// Flag used to indicate when we are shutting down.
@@ -92,12 +86,14 @@ int
ACE_Proactor_Timer_Handler::svc (void)
{
#if defined (ACE_HAS_AIO_CALLS)
+ // @@ Alex, can you please document why this is a "no-op" for the
+ // AIO calls?
return 0;
#else /* ACE_HAS_AIO_CALLS */
u_long time;
ACE_Time_Value absolute_time;
- for (; !this->shutting_down_;)
+ while (this->shutting_down_ == 0)
{
// default value
time = ACE_INFINITE;
@@ -105,15 +101,15 @@ ACE_Proactor_Timer_Handler::svc (void)
// If the timer queue is not empty
if (!this->proactor_.timer_queue ()->is_empty ())
{
- // Get the earliest absolute time
+ // Get the earliest absolute time.
absolute_time
= this->proactor_.timer_queue ()->earliest_time ()
- this->proactor_.timer_queue ()->gettimeofday ();
- // time to wait
+ // Time to wait.
time = absolute_time.msec ();
- // Make sure the time is positive
+ // Make sure the time is positive.
if (time < 0)
time = 0;
}
@@ -129,7 +125,9 @@ ACE_Proactor_Timer_Handler::svc (void)
break;
case ACE_WAIT_FAILED:
// error
- ACE_ERROR_RETURN ((LM_ERROR, ASYS_TEXT ("%p\n"), ASYS_TEXT ("WaitForSingleObject")), -1);
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ASYS_TEXT ("%p\n"),
+ ASYS_TEXT ("WaitForSingleObject")), -1);
}
}
@@ -155,19 +153,19 @@ ACE_Proactor_Handle_Timeout_Upcall::timeout (TIMER_QUEUE &timer_queue,
"(%t) No Proactor set in ACE_Proactor_Handle_Timeout_Upcall, no completion port to post timeout to?!@\n"),
-1);
- // Create the Asynch_Timer
+ // Create the Asynch_Timer.
ACE_Proactor::Asynch_Timer *asynch_timer
= new ACE_Proactor::Asynch_Timer (*handler,
act,
time);
- // Post a completion
+ // Post a completion.
if (this->proactor_->post_completion (asynch_timer) == -1)
- ACE_ERROR_RETURN ((LM_ERROR, "Failure in dealing with timers: PostQueuedCompletionStatus failed\n"), -1);
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Failure in dealing with timers: PostQueuedCompletionStatus failed\n"), -1);
return 0;
}
-
int
ACE_Proactor_Handle_Timeout_Upcall::cancellation (TIMER_QUEUE &timer_queue,
ACE_Handler *handler)
@@ -206,24 +204,21 @@ ACE_Proactor_Handle_Timeout_Upcall::proactor (ACE_Proactor &proactor)
-1);
}
-
-
ACE_Proactor::ACE_Proactor (size_t number_of_threads,
Timer_Queue *tq,
int used_with_reactor_event_loop)
:
#if defined (ACE_HAS_AIO_CALLS)
- #if defined (AIO_LISTIO_MAX)
+#if defined (AIO_LISTIO_MAX)
aiocb_list_max_size_ (AIO_LISTIO_MAX),
- #else /* AIO_LISTIO_MAX */
+#else /* AIO_LISTIO_MAX */
aiocb_list_max_size_ (2),
- #endif /* AIO_LISTIO_MAX */
-
+#endif /* AIO_LISTIO_MAX */
aiocb_list_cur_size_ (0),
#else /* ACE_HAS_AIO_CALLS */
- completion_port_ (0), // This *MUST* be 0, *NOT* ACE_INVALID_HANDLE!!!!
+ // This *MUST* be 0, *NOT* ACE_INVALID_HANDLE!!!!
+ completion_port_ (0),
#endif /* ACE_HAS_AIO_CALLS */
-
number_of_threads_ (number_of_threads),
timer_queue_ (0),
delete_timer_queue_ (0),
@@ -236,8 +231,8 @@ ACE_Proactor::ACE_Proactor (size_t number_of_threads,
ai < this->aiocb_list_max_size_;
ai++)
{
- aiocb_list_ [ai] = 0;
- result_list_ [ai] = 0;
+ aiocb_list_[ai] = 0;
+ result_list_[ai] = 0;
}
ACE_UNUSED_ARG (tq);
#else /* ACE_HAS_AIO_CALLS */
@@ -247,17 +242,22 @@ ACE_Proactor::ACE_Proactor (size_t number_of_threads,
0,
this->number_of_threads_);
if (this->completion_port_ == 0)
- ACE_ERROR ((LM_ERROR, ASYS_TEXT ("%p\n"), ASYS_TEXT ("CreateIoCompletionPort")));
+ ACE_ERROR ((LM_ERROR,
+ ASYS_TEXT ("%p\n"),
+ ASYS_TEXT ("CreateIoCompletionPort")));
// set the timer queue
this->timer_queue (tq);
// Create the timer handler
- ACE_NEW (this->timer_handler_, ACE_Proactor_Timer_Handler (*this));
+ ACE_NEW (this->timer_handler_,
+ ACE_Proactor_Timer_Handler (*this));
// activate <timer_handler>
if (this->timer_handler_->activate (THR_NEW_LWP | THR_DETACHED) == -1)
- ACE_ERROR ((LM_ERROR, ASYS_TEXT ("%p Could not create thread\n"), ASYS_TEXT ("Task::activate")));
+ ACE_ERROR ((LM_ERROR,
+ ASYS_TEXT ("%p Could not create thread\n"),
+ ASYS_TEXT ("Task::activate")));
#endif /* ACE_HAS_AIO_CALLS */
}
@@ -270,11 +270,14 @@ ACE_Proactor::instance (size_t threads)
{
// Perform Double-Checked Locking Optimization.
ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Static_Object_Lock::instance (), 0));
+ *ACE_Static_Object_Lock::instance (),
+ 0));
if (ACE_Proactor::proactor_ == 0)
{
- ACE_NEW_RETURN (ACE_Proactor::proactor_, ACE_Proactor (threads), 0);
+ ACE_NEW_RETURN (ACE_Proactor::proactor_,
+ ACE_Proactor (threads),
+ 0);
ACE_Proactor::delete_proactor_ = 1;
}
}
@@ -290,6 +293,7 @@ ACE_Proactor::instance (ACE_Proactor *r)
*ACE_Static_Object_Lock::instance (), 0));
ACE_Proactor *t = ACE_Proactor::proactor_;
+
// We can't safely delete it since we don't know who created it!
ACE_Proactor::delete_proactor_ = 0;
@@ -328,6 +332,7 @@ ACE_Proactor::run_event_loop (void)
else if (result == -1)
return -1;
}
+
/* NOTREACHED */
return 0;
}
@@ -339,9 +344,11 @@ ACE_Proactor::run_event_loop (ACE_Time_Value &tv)
{
ACE_TRACE ("ACE_Proactor::run_event_loop");
- while (ACE_Proactor::end_event_loop_ == 0 && tv != ACE_Time_Value::zero)
+ while (ACE_Proactor::end_event_loop_ == 0
+ && tv != ACE_Time_Value::zero)
{
int result = ACE_Proactor::instance ()->handle_events (tv);
+
if (ACE_Service_Config::reconfig_occurred ())
ACE_Service_Config::reconfigure ();
@@ -380,6 +387,8 @@ int
ACE_Proactor::close (void)
{
#if defined (ACE_HAS_AIO_CALLS)
+ // @@ Alex, shouldn't we be handling the cleanup of the timer queue
+ // stuff for the POSIX version of the Proactor, as well?!
return 0;
#else /* ACE_HAS_AIO_CALLS */
// Take care of the timer handler
@@ -418,7 +427,7 @@ ACE_Proactor::register_handle (ACE_HANDLE handle,
ACE_UNUSED_ARG (completion_key);
return 0;
#else /* ACE_HAS_AIO_CALLS */
- // No locking is needed here as no state changes
+ // No locking is needed here as no state changes.
ACE_HANDLE cp = ::CreateIoCompletionPort (handle,
this->completion_port_,
(u_long) completion_key,
@@ -429,7 +438,9 @@ ACE_Proactor::register_handle (ACE_HANDLE handle,
// If errno == ERROR_INVALID_PARAMETER, then this handle was
// already registered.
if (errno != ERROR_INVALID_PARAMETER)
- ACE_ERROR_RETURN ((LM_ERROR, ASYS_TEXT ("%p\n"), ASYS_TEXT ("CreateIoCompletionPort")), -1);
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ASYS_TEXT ("%p\n"),
+ ASYS_TEXT ("CreateIoCompletionPort")), -1);
}
return 0;
#endif /* ACE_HAS_AIO_CALLS */
@@ -440,7 +451,10 @@ ACE_Proactor::schedule_timer (ACE_Handler &handler,
const void *act,
const ACE_Time_Value &time)
{
- return this->schedule_timer (handler, act, time, ACE_Time_Value::zero);
+ return this->schedule_timer (handler,
+ act,
+ time,
+ ACE_Time_Value::zero);
}
long
@@ -448,7 +462,10 @@ ACE_Proactor::schedule_repeating_timer (ACE_Handler &handler,
const void *act,
const ACE_Time_Value &interval)
{
- return this->schedule_timer (handler, act, interval, interval);
+ return this->schedule_timer (handler,
+ act,
+ interval,
+ interval);
}
long
@@ -457,8 +474,9 @@ ACE_Proactor::schedule_timer (ACE_Handler &handler,
const ACE_Time_Value &time,
const ACE_Time_Value &interval)
{
- // absolute time
- ACE_Time_Value absolute_time = this->timer_queue_->gettimeofday () + time;
+ // absolute time.
+ ACE_Time_Value absolute_time =
+ this->timer_queue_->gettimeofday () + time;
// Only one guy goes in here at a time
ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->timer_queue_->mutex (), -1);
@@ -491,16 +509,19 @@ ACE_Proactor::cancel_timer (long timer_id,
{
// No need to singal timer event here. Even if the cancel timer was
// the earliest, we will have an extra wakeup.
- return this->timer_queue_->cancel (timer_id, arg, dont_call_handle_close);
+ return this->timer_queue_->cancel (timer_id,
+ arg,
+ dont_call_handle_close);
}
int
ACE_Proactor::cancel_timer (ACE_Handler &handler,
int dont_call_handle_close)
{
- // No need to singal timer event here. Even if the cancel timer was
+ // No need to signal timer event here. Even if the cancel timer was
// the earliest, we will have an extra wakeup.
- return this->timer_queue_->cancel (&handler, dont_call_handle_close);
+ return this->timer_queue_->cancel (&handler,
+ dont_call_handle_close);
}
int
@@ -530,7 +551,6 @@ ACE_Proactor::handle_close (ACE_HANDLE handle,
return this->close ();
}
-
// @@ get_handle () implementation.
ACE_HANDLE
ACE_Proactor::get_handle (void) const
@@ -545,7 +565,6 @@ ACE_Proactor::get_handle (void) const
#endif /* ACE_HAS_AIO_CALLS */
}
-
int
ACE_Proactor::handle_events (ACE_Time_Value &wait_time)
{
@@ -566,20 +585,26 @@ ACE_Proactor::handle_events (unsigned long milli_seconds)
#if defined (ACE_HAS_AIO_CALLS)
// Is there any entries in the list.
if (this->aiocb_list_cur_size_ == 0)
- {
- ACE_DEBUG ((LM_DEBUG, "No AIO pending"));
- return 0;
- }
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "No AIO pending"),
+ 0);
// Wait for asynch operation to complete.
timespec timeout;
timeout.tv_sec = milli_seconds;
timeout.tv_nsec = 0;
+
+ // Alex, I think we want to revise this implementation so that it
+ // DOESN'T need to use aio_suspend, which is going to be
+ // non-scalable since we need to search the aiocb_list... Instead,
+ // we need to use the sigtimedwait(3R) in conjunction with the POSIX
+ // real-time signal mechanism, which should be much more scalable.
+ // Let's talk about how to make this work.
if (aio_suspend (this->aiocb_list_,
this->aiocb_list_max_size_,
&timeout) < 0)
- // If failure is coz of timeout, then return *0* but set errno
- // appropriately. This is what the Win proactor does.
+ // If failure occurs due to timeout, then return *0* but set errno
+ // appropriately. This is what the WinNT proactor does.
if (errno == EINTR)
ACE_ERROR_RETURN ((LM_ERROR,
"(%p):aio_suspend"),
@@ -591,29 +616,37 @@ ACE_Proactor::handle_events (unsigned long milli_seconds)
// Check which aio has finished.
size_t ai;
+
for (ai = 0; ai < this->aiocb_list_max_size_; ai++)
// Analyze error and return values.
- if (aio_error (aiocb_list_ [ai]) != EINPROGRESS)
+ if (aio_error (aiocb_list_[ai]) != EINPROGRESS)
{
- if (aio_return (aiocb_list_ [ai]) < 0)
+ // @@ Alex, should this be == -1 or < 0?
+ if (aio_return (aiocb_list_[ai]) < 0)
ACE_ERROR_RETURN ((LM_ERROR,
"(%p):AIO failed"),
-1);
else
{
- ACE_DEBUG ((LM_DEBUG, "An aio has finished\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ "An aio has finished\n"));
// This AIO is done.
break;
}
}
+
if (ai == this->aiocb_list_max_size_)
// Nothing completed.
return 0;
// Get the values for the completed aio.
size_t bytes_transferred = aiocb_list_[ai]->aio_nbytes;
- void *completion_key = (void *)aiocb_list_[ai]->aio_sigevent.sigev_value.sival_ptr;
- ACE_Asynch_Result *asynch_result = this->result_list_[ai];
+
+ void *completion_key =
+ (void *) aiocb_list_[ai]->aio_sigevent.sigev_value.sival_ptr;
+
+ ACE_Asynch_Result *asynch_result =
+ this->result_list_[ai];
// Invalidate entry in the aiocb list.
delete this->aiocb_list_[ai];
@@ -640,7 +673,6 @@ ACE_Proactor::handle_events (unsigned long milli_seconds)
&completion_key,
&overlapped,
milli_seconds);
-
if (result == FALSE && overlapped == 0)
{
errno = ::GetLastError ();
@@ -816,15 +848,15 @@ ACE_Proactor::insert_to_aiocb_list (aiocb *aiocb_ptr,
for (ai = 0;
ai < this->aiocb_list_max_size_;
ai++)
- if (this->aiocb_list_ [ai] == 0)
+ if (this->aiocb_list_[ai] == 0)
break;
if (ai == this->aiocb_list_max_size_)
return -1;
// Store the pointers.
- this->aiocb_list_ [ai] = aiocb_ptr;
- this->result_list_ [ai] = result;
+ this->aiocb_list_[ai] = aiocb_ptr;
+ this->result_list_[ai] = result;
this->aiocb_list_cur_size_ ++;
return 0;
}
diff --git a/ace/Proactor.h b/ace/Proactor.h
index cfd3d555922..179c01d34f6 100644
--- a/ace/Proactor.h
+++ b/ace/Proactor.h
@@ -10,8 +10,9 @@
// Proactor.h
//
// = AUTHOR
-// Irfan Pyarali (irfan@cs.wustl.edu)
-// Tim Harrison (harrison@cs.wustl.edu)
+// Irfan Pyarali (irfan@cs.wustl.edu),
+// Tim Harrison (harrison@cs.wustl.edu), and
+// Alexander Babu Arulanthu <alex@cs.wustl.edu>
//
// ============================================================================
@@ -29,7 +30,6 @@
#include "ace/Timer_Wheel.h"
#include "ace/Free_List.h"
-
#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || \
(defined (ACE_HAS_AIO_CALLS))
// This only works on Win32 platforms and on Unix platforms supporting
@@ -50,12 +50,12 @@ class ACE_Export ACE_Proactor_Handle_Timeout_Upcall
// Queue to call <handle_timeout> on ACE_Handlers.
public:
friend class ACE_Proactor;
- // Proactor has special privileges
- // Access needed to: proactor ()
+ // Proactor has special privileges, access needed to: proactor ()
typedef ACE_Timer_Queue_T<ACE_Handler *,
ACE_Proactor_Handle_Timeout_Upcall,
- ACE_SYNCH_RECURSIVE_MUTEX> TIMER_QUEUE;
+ ACE_SYNCH_RECURSIVE_MUTEX>
+ TIMER_QUEUE;
ACE_Proactor_Handle_Timeout_Upcall (void);
// Constructor
@@ -64,17 +64,17 @@ public:
ACE_Handler *handler,
const void *arg,
const ACE_Time_Value &cur_time);
- // This method is called when the timer expires
+ // This method is called when the timer expires.
int cancellation (TIMER_QUEUE &timer_queue,
ACE_Handler *handler);
- // This method is called when the timer is canceled
+ // This method is called when the timer is canceled.
int deletion (TIMER_QUEUE &timer_queue,
ACE_Handler *handler,
const void *arg);
- // This method is called when the timer queue is destroyed and
- // the timer is still contained in it
+ // This method is called when the timer queue is destroyed and the
+ // timer is still contained in it.
protected:
int proactor (ACE_Proactor &proactor);
@@ -97,37 +97,46 @@ public:
// Access needed to: thr_mgr_
friend class ACE_Proactor_Handle_Timeout_Upcall;
- // Access needed to: Asynch_Timer, and completion_port_
+ // Access needed to: Asynch_Timer, and completion_port_.
// = Here are the typedefs that the <ACE_Proactor> uses.
+ // @@ Alex, are there any reasons why these typedefs aren't
+ // "capitalized? In general, that's the programming style we
+ // typically use. Can you please take a look and see what depends
+ // on these typedefs to see if we can capitalize them?
typedef ACE_Timer_Queue_T<ACE_Handler *,
ACE_Proactor_Handle_Timeout_Upcall,
- ACE_SYNCH_RECURSIVE_MUTEX> Timer_Queue;
+ ACE_SYNCH_RECURSIVE_MUTEX>
+ Timer_Queue;
typedef ACE_Timer_Queue_Iterator_T<ACE_Handler *,
ACE_Proactor_Handle_Timeout_Upcall,
- ACE_SYNCH_RECURSIVE_MUTEX> Timer_Queue_Iterator;
-
+ ACE_SYNCH_RECURSIVE_MUTEX>
+ Timer_Queue_Iterator;
typedef ACE_Timer_List_T<ACE_Handler *,
ACE_Proactor_Handle_Timeout_Upcall,
- ACE_SYNCH_RECURSIVE_MUTEX> Timer_List;
+ ACE_SYNCH_RECURSIVE_MUTEX>
+ Timer_List;
typedef ACE_Timer_List_Iterator_T<ACE_Handler *,
ACE_Proactor_Handle_Timeout_Upcall,
- ACE_SYNCH_RECURSIVE_MUTEX> Timer_List_Iterator;
-
+ ACE_SYNCH_RECURSIVE_MUTEX>
+ Timer_List_Iterator;
typedef ACE_Timer_Heap_T<ACE_Handler *,
ACE_Proactor_Handle_Timeout_Upcall,
- ACE_SYNCH_RECURSIVE_MUTEX> Timer_Heap;
+ ACE_SYNCH_RECURSIVE_MUTEX>
+ Timer_Heap;
typedef ACE_Timer_Heap_Iterator_T<ACE_Handler *,
ACE_Proactor_Handle_Timeout_Upcall,
- ACE_SYNCH_RECURSIVE_MUTEX> Timer_Heap_Iterator;
-
+ ACE_SYNCH_RECURSIVE_MUTEX>
+ Timer_Heap_Iterator;
typedef ACE_Timer_Wheel_T<ACE_Handler *,
ACE_Proactor_Handle_Timeout_Upcall,
- ACE_SYNCH_RECURSIVE_MUTEX> Timer_Wheel;
+ ACE_SYNCH_RECURSIVE_MUTEX>
+ Timer_Wheel;
typedef ACE_Timer_Wheel_Iterator_T<ACE_Handler *,
ACE_Proactor_Handle_Timeout_Upcall,
- ACE_SYNCH_RECURSIVE_MUTEX> Timer_Wheel_Iterator;
+ ACE_SYNCH_RECURSIVE_MUTEX>
+ Timer_Wheel_Iterator;
ACE_Proactor (size_t number_of_threads = 0,
Timer_Queue *tq = 0,
@@ -139,35 +148,35 @@ public:
static ACE_Proactor *instance (size_t threads = 0);
// Get pointer to a process-wide <ACE_Proactor>. <threads> should
- // be part of another method. It's only here because I'm just a
- // grad student and not in charge. No, I'm not bitter about this.
+ // be part of another method.
static ACE_Proactor *instance (ACE_Proactor *);
// Set pointer to a process-wide <ACE_Proactor> and return existing
// pointer.
static void close_singleton (void);
- // Delete the dynamically allocated Singleton
+ // Delete the dynamically allocated Singleton.
// = Proactor event loop management methods.
+
static int run_event_loop (void);
- // Run the event loop until the <ACE_Proactor::handle_events>
- // method returns -1 or the <end_event_loop> method
- // is invoked.
+ // Run the event loop until the <ACE_Proactor::handle_events> method
+ // returns -1 or the <end_event_loop> method is invoked.
static int run_event_loop (ACE_Time_Value &tv);
- // Run the event loop until the <ACE_Proactor::handle_events>
- // method returns -1, the <end_event_loop> method
- // is invoked, or the <ACE_Time_Value> expires.
+ // Run the event loop until the <ACE_Proactor::handle_events> method
+ // returns -1, the <end_event_loop> method is invoked, or the
+ // <ACE_Time_Value> expires.
static int end_event_loop (void);
- // Instruct the <ACE_Proactor::instance> to terminate its event loop.
+ // Instruct the <ACE_Proactor::instance> to terminate its event
+ // loop.
static int event_loop_done (void);
// Report if the <ACE_Proactor::instance> event loop is finished.
virtual int close (void);
- // Close the IO completion port
+ // Close the IO completion port.
virtual int register_handle (ACE_HANDLE handle,
const void *completion_key);
@@ -220,9 +229,8 @@ public:
virtual int handle_events (ACE_Time_Value &wait_time);
// Dispatch a single set of events. If <wait_time> elapses before
- // any events occur, return.
- // Return 0 on success, non-zero (-1) on timeouts/errors and errno
- // is set accordingly.
+ // any events occur, return. Return 0 on success, non-zero (-1) on
+ // timeouts/errors and errno is set accordingly.
virtual int handle_events (void);
// Block indefinitely until at least one event is dispatched.
@@ -254,15 +262,17 @@ public:
virtual ACE_HANDLE get_handle (void) const;
// Get the event handle.
-
- int insert_to_aiocb_list (aiocb *aiocb_ptr, ACE_Asynch_Result *result);
- // @@
- // This call is for Unix aio_ calls.
- // This method is used by ACE_Asynch_Operation to store some
- // information with the Proactor.
- // Inserting this aiocb_ptr to the array so that aio_return and
- // aio_error can make use of that. Inserting result so that we can
- // call the application back through complete.
+ int insert_to_aiocb_list (aiocb *aiocb_ptr,
+ ACE_Asynch_Result *result);
+ // @@ Alex, is it possible to "hide" this better, i.e., so it's not
+ // in the public interface? Perhaps we could use a "friend"
+ // instead, or better yet, abstract away from this via some other
+ // technique that wouldn't be so "POSIX"-specific.
+ // This call is for POSIX <aio_> calls. This method is used by
+ // <ACE_Asynch_Operation> to store some information with the
+ // Proactor. Inserting this <aiocb_ptr> to the array so that
+ // <aio_return> and <aio_error> can make use of that. Inserting
+ // result so that we can call the application back through complete.
// @@ Can array be full? That means, the aio issue is successful,
// but there are already AIO_LIST_AIO_MAX of calls pending. I will
// have to go for something other than arrays then.
@@ -274,7 +284,7 @@ protected:
virtual int handle_close (ACE_HANDLE handle,
ACE_Reactor_Mask close_mask);
- // Called when object is removed from the ACE_Reactor
+ // Called when object is removed from the ACE_Reactor.
void application_specific_code (ACE_Asynch_Result *asynch_result,
u_long bytes_transferred,
@@ -282,7 +292,7 @@ protected:
const void *completion_key,
u_long error);
// Protect against structured exceptions caused by user code when
- // dispatching handles
+ // dispatching handles.
virtual int handle_events (unsigned long milli_seconds);
// Dispatch a single set of events. If <milli_seconds> elapses
@@ -316,13 +326,11 @@ protected:
// Time value requested by caller
};
-
-
#if defined (ACE_HAS_AIO_CALLS)
- // Let us have an array ot keep track of the all the aio's issued
+ // Let us have an array to keep track of the all the aio's issued
// currently. My intuition is to limit the array size to Maximum
- // Aios that can be issued thru' a lio_list call.
- // @@ AIO_LISTIO_MAX is something else in LynxOS!!!
+ // Aios that can be issued thru' a lio_list call. @@ AIO_LISTIO_MAX
+ // is something else in LynxOS!!!
#if defined (AIO_LISTIO_MAX)
aiocb *aiocb_list_ [AIO_LISTIO_MAX];
ACE_Asynch_Result *result_list_ [AIO_LISTIO_MAX];
@@ -338,25 +346,26 @@ protected:
size_t aiocb_list_cur_size_;
// To maintain the current size of the array (list).
-#else /* ACE_HAS_AIO_CALLS */
+#elif defined (ACE_WIN32)
ACE_HANDLE completion_port_;
// Handle for the completion port.
#endif /* ACE_HAS_AIO_CALLS */
size_t number_of_threads_;
- // This number is passed to the CreatIOCompletionPort() system call
+ // This number is passed to the <CreatIOCompletionPort> system
+ // call.
Timer_Queue *timer_queue_;
- // Timer Queue
+ // Timer Queue.
int delete_timer_queue_;
- // Flag on whether to delete the timer queue
+ // Flag on whether to delete the timer queue.
ACE_Proactor_Timer_Handler *timer_handler_;
- // Handles timeouts events
+ // Handles timeouts events.
ACE_Thread_Manager thr_mgr_;
- // This will manage the thread in the Timer_Handler
+ // This will manage the thread in the Timer_Handler.
ACE_Auto_Event event_;
// This event is used in conjunction with Reactor when we try to
@@ -364,7 +373,7 @@ protected:
int used_with_reactor_event_loop_;
// Flag that indicates whether we are used in conjunction with
- // Reactor
+ // Reactor.
private:
static ACE_Proactor *proactor_;
@@ -381,8 +390,7 @@ private:
#include "ace/Proactor.i"
#endif /* __ACE_INLINE__ */
-#else /* NOT WIN32 */
-
+#else /* NOT WIN32 or POSIX with AIO features. */
class ACE_Export ACE_Proactor
{
public: