diff options
-rw-r--r-- | ChangeLog | 21 | ||||
-rw-r--r-- | ChangeLogs/ChangeLog-02a | 21 | ||||
-rw-r--r-- | ChangeLogs/ChangeLog-03a | 21 | ||||
-rw-r--r-- | THANKS | 1 | ||||
-rw-r--r-- | ace/OS.h | 3 | ||||
-rw-r--r-- | ace/OS.i | 37 | ||||
-rw-r--r-- | ace/Proactor.cpp | 28 | ||||
-rw-r--r-- | ace/Synch.cpp | 5 | ||||
-rw-r--r-- | ace/Synch.h | 6 | ||||
-rw-r--r-- | tests/Makefile | 1 | ||||
-rw-r--r-- | tests/Makefile.bor | 1 | ||||
-rw-r--r-- | tests/Proactor_Timer_Test.cpp | 217 | ||||
-rw-r--r-- | tests/Proactor_Timer_Test.dsp | 108 | ||||
-rw-r--r-- | tests/run_test.lst | 1 |
14 files changed, 446 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog index f7b2d024e82..1510e30579d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +Tue Dec 25 09:30:14 2001 Douglas C. Schmidt <schmidt@macarena.cs.wustl.edu> + + * tests/Makefile: + * tests/Makefile.bor: Added the new Proactor_Timer_Test. + + * tests: Added the new Proactor_Timer_Test.cpp and + Proactor_Timer_Test.dsp. Thanks to Miljenko Norsic for + contributing this. + + * tests/run_test.lst: Added the new Proactor_Timer_Test. + + * ace/OS.{h,i}: Changed the ACE_OS::event_timedwait() method to + allow callers to specify either relative or absolute time. + Thanks to Miljenko Norsic <Miljenko.Norsic@etk.ericsson.se> for + contributing this. + + * ace/Synch.{h,cpp}: Changed the timed wait() method on ACE_Event so + allow callers to specify either relative or absolute time. + Thanks to Miljenko Norsic <Miljenko.Norsic@etk.ericsson.se> for + contributing this. + Tue Dec 25 12:55:56 2001 Carlos O'Ryan <coryan@uci.edu> * Updated all dependencies. diff --git a/ChangeLogs/ChangeLog-02a b/ChangeLogs/ChangeLog-02a index f7b2d024e82..1510e30579d 100644 --- a/ChangeLogs/ChangeLog-02a +++ b/ChangeLogs/ChangeLog-02a @@ -1,3 +1,24 @@ +Tue Dec 25 09:30:14 2001 Douglas C. Schmidt <schmidt@macarena.cs.wustl.edu> + + * tests/Makefile: + * tests/Makefile.bor: Added the new Proactor_Timer_Test. + + * tests: Added the new Proactor_Timer_Test.cpp and + Proactor_Timer_Test.dsp. Thanks to Miljenko Norsic for + contributing this. + + * tests/run_test.lst: Added the new Proactor_Timer_Test. + + * ace/OS.{h,i}: Changed the ACE_OS::event_timedwait() method to + allow callers to specify either relative or absolute time. + Thanks to Miljenko Norsic <Miljenko.Norsic@etk.ericsson.se> for + contributing this. + + * ace/Synch.{h,cpp}: Changed the timed wait() method on ACE_Event so + allow callers to specify either relative or absolute time. + Thanks to Miljenko Norsic <Miljenko.Norsic@etk.ericsson.se> for + contributing this. + Tue Dec 25 12:55:56 2001 Carlos O'Ryan <coryan@uci.edu> * Updated all dependencies. diff --git a/ChangeLogs/ChangeLog-03a b/ChangeLogs/ChangeLog-03a index f7b2d024e82..1510e30579d 100644 --- a/ChangeLogs/ChangeLog-03a +++ b/ChangeLogs/ChangeLog-03a @@ -1,3 +1,24 @@ +Tue Dec 25 09:30:14 2001 Douglas C. Schmidt <schmidt@macarena.cs.wustl.edu> + + * tests/Makefile: + * tests/Makefile.bor: Added the new Proactor_Timer_Test. + + * tests: Added the new Proactor_Timer_Test.cpp and + Proactor_Timer_Test.dsp. Thanks to Miljenko Norsic for + contributing this. + + * tests/run_test.lst: Added the new Proactor_Timer_Test. + + * ace/OS.{h,i}: Changed the ACE_OS::event_timedwait() method to + allow callers to specify either relative or absolute time. + Thanks to Miljenko Norsic <Miljenko.Norsic@etk.ericsson.se> for + contributing this. + + * ace/Synch.{h,cpp}: Changed the timed wait() method on ACE_Event so + allow callers to specify either relative or absolute time. + Thanks to Miljenko Norsic <Miljenko.Norsic@etk.ericsson.se> for + contributing this. + Tue Dec 25 12:55:56 2001 Carlos O'Ryan <coryan@uci.edu> * Updated all dependencies. @@ -1396,6 +1396,7 @@ Jesse <jesse@thrownet.com> Robert Handl <Robert.Handl@era.ericsson.se> Keith Snively <ksnively@d-a-s.com> Ahmed Riza <Ahmed.Riza@ubsw.com> +Miljenko Norsic <Miljenko.Norsic@etk.ericsson.se> I would particularly like to thank Paul Stephenson, who worked with me at Ericsson in the early 1990's. Paul devised the recursive Makefile @@ -5987,7 +5987,8 @@ public: static int event_destroy (ACE_event_t *event); static int event_wait (ACE_event_t *event); static int event_timedwait (ACE_event_t *event, - ACE_Time_Value *timeout); + ACE_Time_Value *timeout, + int use_absolute_time = 1); static int event_signal (ACE_event_t *event); static int event_pulse (ACE_event_t *event); static int event_reset (ACE_event_t *event); @@ -4823,7 +4823,8 @@ ACE_OS::event_wait (ACE_event_t *event) ACE_INLINE int ACE_OS::event_timedwait (ACE_event_t *event, - ACE_Time_Value *timeout) + ACE_Time_Value *timeout, + int use_absolute_time) { #if defined (ACE_WIN32) DWORD result; @@ -4840,16 +4841,27 @@ ACE_OS::event_timedwait (ACE_event_t *event, // that we must convert between absolute time (which is passed // as a parameter) and relative time (which is what // WaitForSingleObjects() expects). - ACE_Time_Value relative_time (*timeout - ACE_OS::gettimeofday ()); - - // Watchout for situations where a context switch has caused the - // current time to be > the timeout. Thanks to Norbert Rapp - // <NRapp@nexus-informatics.de> for pointing this. + // <timeout> parameter is given in absolute or relative value + // depending on parameter <use_absolute_time>. int msec_timeout; - if (relative_time < ACE_Time_Value::zero) - msec_timeout = 0; - else - msec_timeout = relative_time.msec (); + if (use_absolute_time) + { + // Time is given in absolute time, we should use + // gettimeofday() to calculate relative time + ACE_Time_Value relative_time (*timeout - ACE_OS::gettimeofday ()); + + // Watchout for situations where a context switch has caused + // the current time to be > the timeout. Thanks to Norbert + // Rapp <NRapp@nexus-informatics.de> for pointing this. + if (relative_time < ACE_Time_Value::zero) + msec_timeout = 0; + else + msec_timeout = relative_time.msec (); + } + else + // time is given in relative time, just convert it into + // milliseconds and use it + msec_timeout = timeout->msec (); result = ::WaitForSingleObject (*event, msec_timeout); } @@ -4884,6 +4896,11 @@ ACE_OS::event_timedwait (ACE_event_t *event, { event->waiting_threads_++; + // cond_timewait() expects absolute time, check + // <use_absolute_time> flag. + if (use_absolute_time == 0 && timeout != 0) + *timeout += ACE_OS::gettimeofday (); + if (ACE_OS::cond_timedwait (&event->condition_, &event->lock_, timeout) != 0) diff --git a/ace/Proactor.cpp b/ace/Proactor.cpp index 22880a97363..4866480fda0 100644 --- a/ace/Proactor.cpp +++ b/ace/Proactor.cpp @@ -102,27 +102,35 @@ int ACE_Proactor_Timer_Handler::svc (void) { ACE_Time_Value absolute_time; + ACE_Time_Value relative_time; int empty_flag = 0; int result = 0; while (this->shutting_down_ == 0) { - // Is the timer queue empty? - empty_flag = this->proactor_.timer_queue ()->is_empty (); - - if (!empty_flag) + // Check whether the timer queue has any items in it. + if (this->proactor_.timer_queue ()->is_empty () == 0) { // Get the earliest absolute time. absolute_time = this->proactor_.timer_queue ()->earliest_time (); - // Block for absolute time. - result = this->timer_event_.wait (&absolute_time); + // Get current time from timer queue since we don't know + // which <gettimeofday> was used. + ACE_Time_Value cur_time = this->proactor_.timer_queue ()->gettimeofday (); + + // Compare absolute time with curent time received from the + // timer queue. + if (absolute_time > cur_time) + relative_time = absolute_time - cur_time; + else + relative_time = 0; + + // Block for relative time. + result = this->timer_event_.wait (&relative_time, 0); } else - { - // Wait for ever. - result = this->timer_event_.wait (); - } + // The timer queue has no entries, so wait indefinitely. + result = this->timer_event_.wait (); // Check for timer expiries. if (result == -1) diff --git a/ace/Synch.cpp b/ace/Synch.cpp index 01a446cd323..6b81248db41 100644 --- a/ace/Synch.cpp +++ b/ace/Synch.cpp @@ -306,10 +306,11 @@ ACE_Event::wait (void) } int -ACE_Event::wait (const ACE_Time_Value *abstime) +ACE_Event::wait (const ACE_Time_Value *abstime, int use_absolute_time) { return ACE_OS::event_timedwait (&this->handle_, - (ACE_Time_Value *) abstime); + (ACE_Time_Value *) abstime, + use_absolute_time); } int diff --git a/ace/Synch.h b/ace/Synch.h index 6a7d09d1548..f46053bef2b 100644 --- a/ace/Synch.h +++ b/ace/Synch.h @@ -857,8 +857,10 @@ public: int wait (void); /// Same as wait() above, but this one can be timed - /// <abstime> is absolute time-of-day. - int wait (const ACE_Time_Value *abstime); + /// <abstime> is absolute time-of-day if if <use_absolute_time> + /// is non-0, else it is relative time. + int wait (const ACE_Time_Value *abstime, + int use_absolute_time = 1); /** * if MANUAL reset diff --git a/tests/Makefile b/tests/Makefile index 05da7139f17..697dff7bc7f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -63,6 +63,7 @@ BIN = Aio_Platform_Test \ OrdMultiSet_Test \ OS_Test \ Proactor_Test \ + Proactor_Timer_Test \ Process_Mutex_Test \ Process_Strategy_Test \ Priority_Buffer_Test \ diff --git a/tests/Makefile.bor b/tests/Makefile.bor index 9e81517be1f..fa5591c8bc4 100644 --- a/tests/Makefile.bor +++ b/tests/Makefile.bor @@ -64,6 +64,7 @@ NAMES = \ OS_Test \ Pipe_Test \ Proactor_Test \ + Proactor_Timer_Test \ Priority_Buffer_Test \ Priority_Reactor_Test \ Priority_Task_Test \ diff --git a/tests/Proactor_Timer_Test.cpp b/tests/Proactor_Timer_Test.cpp new file mode 100644 index 00000000000..c215d0aedc5 --- /dev/null +++ b/tests/Proactor_Timer_Test.cpp @@ -0,0 +1,217 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Proctor_Timer_Test.cpp +// +// = DESCRIPTION +// This is a simple test that illustrates the timer mechanism of +// the <ACE_Proactor>. Scheduling timers, handling expired timers and +// cancelling scheduled timers are all exercised in this test. +// +// = AUTHOR +// Prashant Jain <pjain@cs.wustl.edu>, +// Douglas C. Schmidt <schmidt@cs.wustl.edu>, and +// Miljenko Norsic <Miljenko.Norsic@etk.ericsson.se> +// +// ============================================================================ + +#include "test_config.h" +#include "ace/Timer_Queue.h" +#include "ace/Proactor.h" +#include "ace/High_Res_Timer.h" +#include "ace/Asynch_IO.h" + +static int done = 0; +static int count = 0; +static int odd = 0; + +class Time_Handler : public ACE_Handler +{ +public: + Time_Handler (); + // Default constructor + + virtual void handle_time_out (const ACE_Time_Value &tv, const void *arg); + // Handle the timeout. + + long timer_id (void) const; + // Return our timer id. + + void timer_id (long); + // Set our timer id; + +private: + long timer_id_; + // Stores the id of this timer. +}; + +Time_Handler::Time_Handler () +: timer_id_ (-1) +{ + // Nothing +} + +void +Time_Handler::handle_time_out (const ACE_Time_Value &tv, const void *arg) +{ + long current_count = ACE_reinterpret_cast (long, arg); + if (current_count >= 0) + ACE_ASSERT (current_count == count); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("[%x] Timer id %d with count #%d|%d timed out at %d!\n"), + this, + this->timer_id (), + count, + current_count, + tv.sec ())); + + if (current_count == long (ACE_MAX_TIMERS - 1)) + done = 1; + else if (count == ACE_MAX_TIMERS - 1) + { + done = 1; + return; + } + else if (current_count == -1) + { + int result = ACE_Proactor::instance ()->cancel_timer (this->timer_id ()); + result = ACE_Proactor::instance ()->schedule_timer(*this, + (const void *) -1, + ACE_Time_Value(count + 1)); + ACE_ASSERT (result != -1); + this->timer_id(result); + } + count += (1 + odd); + return; +} + +long +Time_Handler::timer_id (void) const +{ + return this->timer_id_; +} + +void +Time_Handler::timer_id (long t) +{ + this->timer_id_ = t; +} + +static void +test_registering_all_handlers (void) +{ + ACE_Trace t (ACE_TEXT ("test_registering_all_handler"), + __LINE__, + ACE_TEXT_CHAR_TO_TCHAR (__FILE__)); + Time_Handler rt[ACE_MAX_TIMERS]; + int t_id[ACE_MAX_TIMERS]; + + for (size_t i = 0; i < ACE_MAX_TIMERS; i++) + { + t_id[i] = + ACE_Proactor::instance ()->schedule_timer (rt[i], + (const void *) i, + ACE_Time_Value (2 * i + 1)); + ACE_ASSERT (t_id[i] != -1); + rt[i].timer_id (t_id[i]); + } + + while (!done) + ACE_Proactor::instance ()->handle_events (); +} + +static void +test_registering_one_handler (void) +{ + ACE_Trace t (ACE_TEXT ("test_registering_one_handler"), + __LINE__, + ACE_TEXT_CHAR_TO_TCHAR (__FILE__)); + Time_Handler rt[ACE_MAX_TIMERS]; + int t_id[ACE_MAX_TIMERS]; + + done = 0; + count = 0; + + for (size_t i = 0; (u_long) i < ACE_MAX_TIMERS; i++) + { + t_id[i] = + ACE_Proactor::instance ()->schedule_timer (rt[0], + (const void *) i, + ACE_Time_Value (2 * i + 1)); + ACE_ASSERT (t_id[i] != -1); + } + + while (!done) + ACE_Proactor::instance ()->handle_events (); +} + +static void +test_canceling_odd_timers (void) +{ + ACE_Trace t (ACE_TEXT ("test_canceling_odd_timers"), + __LINE__, + ACE_TEXT_CHAR_TO_TCHAR (__FILE__)); + Time_Handler rt[ACE_MAX_TIMERS]; + int t_id[ACE_MAX_TIMERS]; + + done = 0; + count = 1; + odd = 1; + + for (size_t i = 0; (u_long) i < ACE_MAX_TIMERS; i++) + { + t_id[i] = ACE_Proactor::instance ()->schedule_timer (rt[i], + (const void *) i, + ACE_Time_Value (2 * i + 1)); + ACE_ASSERT (t_id[i] != -1); + rt[i].timer_id (t_id[i]); + } + + for (size_t j = 0; (u_long) j < ACE_MAX_TIMERS; j++) + // Cancel handlers with odd numbered timer ids. + if (ACE_ODD (rt[j].timer_id ())) + { + int result = + ACE_Proactor::instance ()->cancel_timer (rt[j].timer_id ()); + ACE_ASSERT (result != -1); + } + + while (!done) + ACE_Proactor::instance ()->handle_events (); +} + +// If any command line arg is given, run the test with high res timer +// queue. Else run it normally. +int +main (int argc, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Proactor_Timer_Test")); + + if (argc > 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Running with high-res timer queue\n"))); + ACE_Proactor *r = ACE_Proactor::instance (); + (void) ACE_High_Res_Timer::global_scale_factor (); + r->timer_queue ()->gettimeofday (&ACE_High_Res_Timer::gettimeofday_hr); + } + + // Register all different handlers, i.e., one per timer. + test_registering_all_handlers (); + + // Now try multiple timers for ONE event handler (should produce the + // same result). + test_registering_one_handler (); + + // Try canceling handlers with odd numbered timer ids. + test_canceling_odd_timers (); + + ACE_END_TEST; + return 0; +} diff --git a/tests/Proactor_Timer_Test.dsp b/tests/Proactor_Timer_Test.dsp new file mode 100644 index 00000000000..9e4782494b7 --- /dev/null +++ b/tests/Proactor_Timer_Test.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="Proactor_Timer_Test" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Proactor_Timer_Test - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Proactor_Timer_Test.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Proactor_Timer_Test.mak" CFG="Proactor_Timer_Test - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Proactor_Timer_Test - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "Proactor_Timer_Test - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Proactor_Timer_Test - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\ace"
+
+!ELSEIF "$(CFG)" == "Proactor_Timer_Test - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "../" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\ace"
+
+!ENDIF
+
+# Begin Target
+
+# Name "Proactor_Timer_Test - Win32 Release"
+# Name "Proactor_Timer_Test - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Proactor_Timer_Test.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\test_config.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/tests/run_test.lst b/tests/run_test.lst index dd72c776fb4..e5523a79a79 100644 --- a/tests/run_test.lst +++ b/tests/run_test.lst @@ -76,6 +76,7 @@ Priority_Buffer_Test Priority_Reactor_Test: !chorus Priority_Task_Test: !Unicos Proactor_Test: Win32 +Proactor_Timer_Test: Win32 Process_Manager_Test: ALL MSVC !DISABLED Process_Mutex_Test: !MSVC !chorus !VxWorks Process_Strategy_Test: !chorus !LynxOS !VxWorks |