gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash/cygnal ACT/ACT.hpp ACT/Change_Log.txt ACT...


From: Eric Hughes
Subject: [Gnash-commit] gnash/cygnal ACT/ACT.hpp ACT/Change_Log.txt ACT...
Date: Tue, 10 Jul 2007 14:09:12 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Eric Hughes <eh9>       07/07/10 14:09:12

Modified files:
        cygnal/ACT     : ACT.hpp Change_Log.txt Cygnal_Instances.cpp 
                         Scheduler.cpp Scheduler.hpp 
                         Scheduling_Queue.hpp Service.cpp Service.hpp 
        cygnal/ACT/test_support: Action_Tracing.hpp 
                                 Listening_Actions.cpp 
                                 Listening_Actions.hpp 
                                 Simple_Actions.cpp Simple_Actions.hpp 
        cygnal/ACT/unit_tests: Test_ACT.cpp Test_Scheduler.cpp 
                               Test_Scheduling_Queue.cpp 
        cygnal/HTTP    : HTTP_Behavior.cpp HTTP_Behavior.hpp 
                         HTTP_Parse.cpp HTTP_Parse.hpp URI.cpp URI.hpp 
        cygnal/HTTP/unit_tests: Test_HTTP.cpp 
        cygnal/IO      : IO_Device.hpp IO_Generator.cpp IO_Generator.hpp 
                         Stream_Consumer.cpp Stream_Consumer.hpp 
        cygnal/IO/test_support: Null_Device.cpp Null_Device.hpp 
                                Null_Filter.cpp Null_Filter.hpp 
                                String_Device.cpp String_Device.hpp 
                                String_Generator.cpp 
                                String_Generator.hpp 
        cygnal/IO/unit_tests: Test_Service.cpp 
        cygnal/Net     : Net.hpp Old_Device.hpp socket_device.cpp 
                         socket_device.hpp 
        cygnal/Net/unit_tests: Test_socket_device.cpp 
        cygnal/unit_tests: Permutation.hpp Random_Permutation.cpp 
                           Test_Support.hpp 
Added files:
        cygnal/ACT     : ACT.doxygen.txt Handle.cpp Handle.hpp 
                         Listen.T.cpp Listen.hpp Pause_Demon.cpp 
                         Pause_Demon.hpp Scheduler.T.cpp 
        cygnal/ACT/test_support: Supplied_Service.cpp 
                                 Supplied_Service.hpp 
        cygnal/HTTP    : Change_Log.txt 
        cygnal/Net     : Change_Log.txt 
        cygnal         : Aspect.hpp Change_Log.txt mainpage.doxygen.txt 
        cygnal/doc     : Doxyfile 
Removed files:
        cygnal/ACT     : Pause_Service.cpp Pause_Service.hpp 

Log message:
        ACT module to alpha quality.  Two major steps were to get listener 
actions and monitors working and to get the aspect templates and white box 
testing working.
        Performed a few renamings and retypings of fundamental concepts, so 
textual changes are extensive.
        Wrote a first pass of module documentation, so things aren't completely 
opaque.
        Added Change_Log.txt in each module; see them for details.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/ACT.hpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Change_Log.txt?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Cygnal_Instances.cpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Scheduler.cpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Scheduler.hpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Scheduling_Queue.hpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Service.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Service.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/ACT.doxygen.txt?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Handle.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Handle.hpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Listen.T.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Listen.hpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Pause_Demon.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Pause_Demon.hpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Scheduler.T.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Pause_Service.cpp?cvsroot=gnash&r1=1.2&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/Pause_Service.hpp?cvsroot=gnash&r1=1.2&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/test_support/Action_Tracing.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/test_support/Listening_Actions.cpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/test_support/Listening_Actions.hpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/test_support/Simple_Actions.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/test_support/Simple_Actions.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/test_support/Supplied_Service.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/test_support/Supplied_Service.hpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/unit_tests/Test_ACT.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/unit_tests/Test_Scheduler.cpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/ACT/unit_tests/Test_Scheduling_Queue.cpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/HTTP/HTTP_Behavior.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/HTTP/HTTP_Behavior.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/HTTP/HTTP_Parse.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/HTTP/HTTP_Parse.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/HTTP/URI.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/HTTP/URI.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/HTTP/Change_Log.txt?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/HTTP/unit_tests/Test_HTTP.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/IO_Device.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/IO_Generator.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/IO_Generator.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/Stream_Consumer.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/Stream_Consumer.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/test_support/Null_Device.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/test_support/Null_Device.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/test_support/Null_Filter.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/test_support/Null_Filter.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/test_support/String_Device.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/test_support/String_Device.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/test_support/String_Generator.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/test_support/String_Generator.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/IO/unit_tests/Test_Service.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/Net/Net.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/Net/Old_Device.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/Net/socket_device.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/Net/socket_device.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/Net/Change_Log.txt?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/Net/unit_tests/Test_socket_device.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/unit_tests/Permutation.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/unit_tests/Random_Permutation.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/unit_tests/Test_Support.hpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/Aspect.hpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/Change_Log.txt?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/mainpage.doxygen.txt?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/doc/Doxyfile?cvsroot=gnash&rev=1.1

Patches:
Index: ACT/ACT.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/ACT.hpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- ACT/ACT.hpp 1 Jul 2007 10:53:50 -0000       1.3
+++ ACT/ACT.hpp 10 Jul 2007 14:09:08 -0000      1.4
@@ -19,7 +19,7 @@
 //
 
 /**    \file ACT.hpp
- *     Asynchronous Computation Task
+ *     \brief Asynchronous Computation Task
  */
 
 #pragma once
@@ -31,21 +31,83 @@
 using boost::shared_ptr ;
 
 namespace ACT {
-
-       class wakeup_listener ;
-
        //-------------------------
-       /** \enum act_state
-        *      \brief Generically relevant ACT states.
+       /** \class ACT_State
+        *      \brief Generically state of an ACT as a scheduler and other 
actions see it.
         *
-        *      There are exactly three generic ACT states.
-        *      Particular kinds of ACT may refine this set of states, but they 
must also preserve the meaning of these three.
-        *      - Working.  Not yet finished.
-        *      - Completed.  Finished normally.
-        *      - Bad.  Finished abnormally.
+        *      This enumeration is at the core of the control flow idiom of 
the ACT environment.
+        *      When a scheduler or another action calls an action, the action 
may complete its call before it completes its embodied operation.
+        *      The states break down as follows:
+        *      - Action is not finished.
+        *              In this case, the operation is not yet finished and is 
still working.
+        *              Further calls to this action will be necessary to get 
to a finished state,
+        *                      which will not happen autonomously.
+        *              This state comes in two varieties.
+        *              - Ready. 
+        *                      The action spontaneously yielded control.
+        *                      An immediate call to this action would 
immediately continue.
+        *              - Waiting.
+        *                      The action returned because it would block 
otherwise.
+        *                      An immediate call to this action is unlikely to 
do anything else.
+        *      - Action has finished.
+        *              One way or another, this action has finished its 
processing.
+        *              Further calls to this action do nothing.
+        *              - Completed.  
+        *                      The action has finished and its ordinary 
postconditions may be relied upon.
+        *              - Bad.  
+        *                      The action has entered an abnormal state and 
its ordinary postconditions need not be true.
+        *                      As a rule, actions in this state terminated 
early.
+        *
+        *      An important aspect of the Waiting state is that an action that 
returns this state
+        *              has accepted responsibility for setting in motion its 
own later wake-up.
+        *      The scheduler does not do this, since it doesn't deal in 
specifics.
         */
-       enum act_state { Working, Completed, Bad } ;
+       class ACT_State
+       {
+       public:
+               /// Symbolic names for the return states of an action.
+               enum state {
+                       /// Not finished.  Ready to continue immediately.
+                       Ready,
+                       /// Not finished.  Presumed not ready.
+                       Would_Block,
+                       /// Finished normally.
+                       Completed,
+                       /// Abnormal termination; now finished.
+                       Bad
+               } ;
+
+       private:
+               /// This class is a wrapper around this state.
+               state x ;
+
+       public:
+               /// Ordinary constructor
+               ACT_State( state x ) : x( x ) {} ;
+
+               /// Ordinary assignment
+               ACT_State & operator=( state y ) { x = y ; return * this ; }
+
+               /// Convenience test.
+               inline bool ready() const { return x == Ready ; }
+
+               /// Convenience test.
+               inline bool would_block() const { return x == Would_Block ; }
+
+               /// Convenience test.
+               inline bool completed() const { return x == Completed ; }
+
+               /// Convenience test.
+               inline bool bad() const { return x == Bad ; }
 
+               /// Test whether state is an unfinished (i.e. still working) 
state.
+               /// If true, it's either Ready or Waiting.
+               inline bool working() const { return x <= Would_Block ; }
+       } ;
+
+       //-------------------------
+       // Forward
+       class wakeup_listener ;
        //-------------------------
        /**     \class basic_act
         *      \brief Base class for specific ACT uses.
@@ -72,7 +134,6 @@
         *      The basic idea of an ACT splits the keyword "return" into two 
different kinds.
         *      - The ordinary "return", which indicates completion of the task.
         *              This is represented by the states \c Completed and \c 
Bad.
-        *              This kind of
         *      - An interruption "yield", which indicates not-yet-completion 
of the task.
         *              This is represented by the state \c Working.
         *
@@ -104,47 +165,53 @@
         */
        class basic_act {
                /// Child classes may access and alter the internal state.
-               act_state the_state ;
+               ACT_State the_state ;
 
        protected:
                /// Protected constructor for child classes.
                basic_act() 
-                       : the_state( Working )
+                       : the_state( ACT_State::Ready )
                {}
 
                /// Protected setter for subclass implementation.
-               inline act_state set_working() { return the_state = Working ; }
+               inline ACT_State set_ready() { return the_state = 
ACT_State::Ready ; }
 
                /// Protected setter for subclass implementation.
-               inline act_state set_completed() { return the_state = Completed 
; }
+               inline ACT_State set_would_block() { return the_state = 
ACT_State::Would_Block ; }
 
                /// Protected setter for subclass implementation.
-               inline act_state set_bad() { return the_state = Bad ; }
+               inline ACT_State set_completed() { return the_state = 
ACT_State::Completed ; }
+
+               /// Protected setter for subclass implementation.
+               inline ACT_State set_bad() { return the_state = ACT_State::Bad 
; }
 
                /// Protected arbitrary setter for subclasses that filter.
-               inline act_state set_state( act_state x ) { return the_state = 
x ; }
+               inline ACT_State set_state( ACT_State x ) { return the_state = 
x ; }
 
        public:
                ///
-               inline act_state internal_state() { return the_state ; }
+               inline ACT_State internal_state() { return the_state ; }
 
                /// 
-               inline bool working() const { return the_state == Working ; }
+               inline bool ready() const { return the_state.ready() ; }
 
                /// 
-               inline bool completed() const
-               {
-                       return the_state == Completed ;
-               }
+               inline bool would_block() const { return 
the_state.would_block() ; }
+
+               /// Return is whether this action is in an unfinished state 
(either Ready or Waiting)
+               inline bool working() const { return the_state.working() ; }
+
+               /// 
+               inline bool completed() const { return the_state.completed() ; }
 
                /// 
-               inline bool bad() const { return the_state == Bad ; }
+               inline bool bad() const { return the_state.bad() ; }
 
                ///
-               virtual act_state operator()( void ) =0 ;
+               virtual ACT_State operator()( void ) =0 ;
 
                ///
-               virtual act_state operator()( wakeup_listener * ) =0 ;
+               virtual ACT_State operator()( wakeup_listener * ) =0 ;
 
        } ;
 
@@ -161,13 +228,13 @@
                 *      It is reasonable to consider this as an analogue of a 
thread body.
                 *
                 *      \pre 
-                *      - the_state == Working.
+                *      - the_state is working.
                 *              (Note: operator(), acting as a facade, ensures 
this predicate.)
                 *      \post
                 *      - the_state == Working implies success conditions are 
not yet met nor are they yet precluded.
                 *      - return == internal_state().
                 */
-               virtual act_state run( void ) =0 ;
+               virtual ACT_State run( void ) =0 ;
 
        public:
                /**     \brief operator() is a facade for the body of an ACT.
@@ -176,13 +243,13 @@
                 *      - the_state == Working implies success conditions are 
not yet met nor are they yet precluded.
                 *      - return == internal_state().
                 */
-               inline act_state operator()( void )
+               inline ACT_State operator()( void )
                {
                        if ( ! working() ) return internal_state() ;
                        return run() ;
                }
 
-               inline act_state operator()( wakeup_listener * )
+               inline ACT_State operator()( wakeup_listener * )
                {
                        return operator()() ;
                }
@@ -212,7 +279,7 @@
                 *              wakeup_listener may be called when progress on 
the ACT is possible.
                 *
                 *      \note
-                *      The postcondition is not a guarantee that a \c 
wakeup_listener <b>will</b> be called,
+                *      The postcondition is not a guarantee that a 
wakeup_listener <b>will</b> be called,
                 *              but rather that a reliance upon the caller that 
this instance <b>may</b> call
                 *              the listener (assuming it's not null).
                 *      Certain ACT's may provide such a guarantee that they 
will call.
@@ -220,7 +287,7 @@
                 *              when I/O is available.
                 *
                 *      \note
-                *      The input parameter \c wakeup_listener may indeed be 
zero.
+                *      The input parameter wakeup_listener may indeed be zero.
                 *      The intent behind this choice is to enable a scheduler 
to forbid an ACT
                 *              from setting up a background poll or 
notification.
                 *      Should a scheduler do this, it must assume the 
responsibility for checking back later.
@@ -236,19 +303,22 @@
                 *              recently executed" policy for selecting the 
next ACT to run.
                 *      Furthermore, these policies might be blended, putting 
"slow" operations into
                 *              notification mode and "fast" operations into 
direct retry mode.
+                *
+                *      \sa
+                *      ACT_State: For more detailed information on the meaning 
of the return value.
                 */
-               virtual act_state run( wakeup_listener * ) =0 ;
+               virtual ACT_State run( wakeup_listener * ) =0 ;
 
        public:
                ///
-               inline act_state operator()( wakeup_listener * w )
+               inline ACT_State operator()( wakeup_listener * w )
                {
                        if ( ! working() ) return internal_state() ;
                        return run( w ) ;
                }
 
                /// Convenience zero-parameter operator() ;
-               inline act_state operator()() { return operator()( 0 ) ; }
+               inline ACT_State operator()() { return operator()( 0 ) ; }
        } ;
 
        //-------------------------
@@ -257,7 +327,7 @@
         *      Allows hiding 'new' allocation and avoiding defective memory 
management.
         *      Enables passing ACT instances by copying pointers.
         *
-        *      \inv
+        *      \invariant
         *              the_body != 0
         *
         */
@@ -288,7 +358,7 @@
 
                /** Proxy for the body's function operator
                 */
-               act_state operator()( wakeup_listener * x ) {
+               ACT_State operator()( wakeup_listener * x ) {
                        if ( working() ) {
                                return the_body -> operator()( x ) ;
                        }

Index: ACT/Change_Log.txt
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/Change_Log.txt,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- ACT/Change_Log.txt  19 Jun 2007 18:52:25 -0000      1.1
+++ ACT/Change_Log.txt  10 Jul 2007 14:09:08 -0000      1.2
@@ -1,3 +1,133 @@
+Change Log for GNU Cygnal, Module ACT
+=====================================
+
+2007-07-10 Eric Hughes <address@hidden>
+       * Pause_Demon.[hc]pp: Renamed from Pause_Service.[hc]pp.
+       * ACT/unit_tests/Test_Scheduler.cpp: Added finished_at_bound() to 
scheduler test aspect.  (Re-)Wrote a proper pause demon test.
+       * ACT/ACT.doxygen.txt: Added more environment documentation.
+
+2007-07-09 Eric Hughes <address@hidden>
+       * Scheduler.hpp, Scheduler.cpp, Scheduler.T.cpp: Renamed scheduler 
category Service to Demon to get rid of a name collision.
+
+2007-07-06 Eric Hughes <address@hidden>
+       * ACT.hpp, Handle.cpp, Listen.T.cpp, Pause_Service.hpp, Scheduler.hpp, 
Scheduler.T.cpp, Scheduling_Queue.hpp, Service.hpp, 
test_support/Action_Tracing.hpp, test_support/Simple_Actions.hpp, 
test_support/Supplied_Service.hpp: Comment cleanup for doxygen.
+       * unit_tests/Test_Scheduler.cpp: Put everything into namespace 
ACT_Test.  New doxygen comments.
+
+2007-07-05 Eric Hughes <address@hidden>
+       * ../Aspect.hpp: Put declarations within namespace \c aspect.
+       * Cygnal_Instances.cpp, Handle.hpp, Scheduler.hpp, Service.hpp, 
test_support/Supplied_Service.hpp, unit_tests/Test_Scheduler.cpp: Added aspect 
namespace declarations.  Put specializations of null aspects into proper 
namespace block.
+
+2007-07-04 Eric Hughes <address@hidden>
+       * Scheduler.T.cpp: Renamed from Scheduler_T.cpp.
+       * Cygnal_Instances.cpp, unit_tests/Test_Scheduler.cpp, 
unit_tests/Test_Scheduling_Queue.cpp: Changed file name references.
+       * Listen.hpp: Added documentation.
+       * Listen.cpp: Added documentation.  Slightly changed removal loop.
+       * test_support/Listening_Actions.[hc]pp: Moved null constructor to 
header. Fixed comments.  Removed unused member.
+
+2007-07-04 Eric Hughes <address@hidden>
+       * Listen.hpp, Listen.T.cpp, test_support/Listening_Actions.[hc]pp: 
Factored out monitor base class from N_to_completion_Monitor.
+
+2007-07-04 Eric Hughes <address@hidden>
+       * Listen.hpp, Listen.T.cpp, test_support/Listening_Actions.[hc]pp: 
Extracted generic listening base class from N_to_completion.
+
+2007-07-03 Eric Hughes <address@hidden>
+       * Scheduler_T.cpp: Renamed from Scheduler_Templated.cpp.
+       * Cygnal_Instances.cpp, unit_tests/Test_Scheduler.cpp: Renamed file 
name references.
+
+2007-07-03 Eric Hughes <address@hidden>
+       * Scheduler.hpp, Scheduler_Templated.cpp: Removed execution loop with 
bound.  Augmented aspect points.
+       * unit_tests/Test_Scheduler.cpp: Wrote test aspect for scheduler with 
an execution bound.  Converted all test cases to use it.
+
+2007-07-02 Eric Hughes <address@hidden>
+       * Scheduler.hpp: Made Scheduler and wakeup_listener virtual base 
classes.  
+       * Scheduler.hpp, Scheduling_Queue.hpp: Added template parameters to 
wakeup_listener_allocated and Basic_Wakeup_Listener.  
+       * Scheduler.hpp, Scheduler_Templated.cpp: Added aspect to 
Basic_Scheduler.
+       * Scheduler_Templated.cpp, Scheduler.cpp: Moved wake up listener code 
from non-template to template source.     
+       * Cygnal_Instances.cpp: Instantiate Basic_Scheduler directly, now that 
Scheduler is an interface.
+       * Handle.hpp: Added inline declarations for aspect class.
+       * unit_tests/Test_Scheduler.cpp: Added test aspect for Basic_Scheduler.
+       * unit_tests/Test_Scheduling_Queue.cpp: Added more explicit template 
instantiations.
+
+2007-06-30 Eric Hughes <address@hidden>
+       * test_support/Listening_Actions.[hc]pp: Changed follower registry for 
listening monitors to use weak pointers.
+
+2007-06-30 Eric Hughes <address@hidden>
+       * Service.[hc]pp: Enabled testing a Generator for completion so that a 
Service may complete.
+       * test_support/Supplied_Service.[hc]pp: Added shutdown completion to 
Supplied_Service.
+       * unit_tests/Test_Scheduler.cpp: Augmented service test to add shutdown.
+
+2007-06-29 Eric Hughes <address@hidden>
+       * Scheduler.[hc]pp, Scheduler_Templated.cpp: renamed enumeration 
identifier Service to action_Service.
+       * Service.[hc]pp: Added aspect to class Service. Base aspect defines 
two points, one each at the beginning and end of run().
+       * Supplied_Service.[hc]pp: Used Service aspect to enable tracking of 
Service::run().
+
+2007-06-29 Eric Hughes <address@hidden>
+       * Cygnal_Instances.cpp: Included Handle.cpp to get the handle class 
instantiated also.
+       * Scheduler.hpp, Scheduler_Templated.hpp: Added Handled as parent class 
of Basic_Scheduler.
+       * test_support/Listening_Actions.[hc]pp: Used Handle_Registry_Follower 
to enable one monitor per scheduler, rather than one monitor per class.
+       * test_support/Supplied_Service.hpp, unit_tests/Test_Scheduler.cpp: 
Added tracker to Supplied_Service constructor.
+
+2007-06-29 Eric Hughes <address@hidden>
+       * ../Aspect.hpp: Cleaned up set_owner definitions and inheritance 
idiom.  Renamed Aspect_Base to Null_Aspect_Base.
+       * Scheduler.hpp: Added aspect to Basic_Scheduler (as-yet unused).  Made 
typedef so that external code can just use symbol 'Scheduler'.
+       * Scheduler.cpp, Scheduler_Templated.cpp, Cyngal_Instances.cpp: Split 
template member definitions into separate file for inclusion and explicit 
instantiation.  Avoids multiple definitions of non-template classes.
+       * Handle.hpp, unit_tests/Test_Scheduler.cpp: Split null aspect for 
Handled as per new idiom. Cleaned up test aspect definitions accordingly.
+       * Pause_Service.hpp, Service.[ch]pp, test_support/Supplied_Service.hpp, 
unit_tests/Test_Scheduler.cpp: Replaced 'Basic_Scheduler' with 'Scheduler'.
+
+2007-06-28 Eric Hughes <address@hidden>
+       * ../Aspect.hpp: Added arity-2 null aspect.
+       * Handle.[hc]pp: Added Marker classes for Handle, etc. to isolate use 
of indices.
+       * unit_tests/Test_Scheduler.cpp: Added arity-2 test aspect; updated 
test to use markers.
+
+2007-06-27 Eric Hughes <address@hidden>
+       * Handle.[hc]pp: Finished implementation of Handle_Registry_Follower, 
including its null aspect. Added new proxies for Vector_with_Handle_Index.
+       * unit_tests/Test_Scheduler.cpp: New unit test for 
Handle_Registry_Follower, including a test aspect.
+
+2007-06-27 Eric Hughes <address@hidden>
+       * Handle.hpp: Beginning of an implementation of 
Handle_Registry_Follower.
+       * test_support/Simple_Actions.hpp: Removed extraneous (and previous) 
definition of class N_to_completion.
+       * Many small comment modification to doxygen comments.
+       
+2007-06-27 Eric Hughes <address@hidden>
+       * Handle.[hc]pp, unit_tests/Test_Scheduler.cpp: Renamed Handle_Registry 
to Handle_Registry_Leader.
+
+2007-06-26 Eric Hughes <address@hidden>
+       * ../Aspect.hpp: Added Aspect_Has_Access_To_Owner to make owner access 
generic.
+       * Handle.hpp: Changed initialization of aspect owner pointer.
+       * unit_tests/Test_Scheduler.cpp: Reworked owner access with new classes.
+
+2007-06-26 Eric Hughes <address@hidden>
+       * Handle.hpp: Renamed Handled::at() to Handled::registry_at().
+
+2007-06-25 Eric Hughes <address@hidden>
+       * ../Aspect.cpp: Changed instantiation order for aspects for technical 
reasons involving self-reference in template parameters.
+       * Handle.hpp: Added typedefs for aspect_type and friend declarations.
+       * Handle.cpp: Changed template declarations to match new aspect idiom.
+       * unit_tests/Test_Scheduler.cpp: Completed the white box test for 
Handled.  It passes.
+
+2007-06-23 Eric Hughes <address@hidden>
+       * Handle.hpp: Added Handle_Registry::remove() and Handle::~Handle().
+       * Handle.cpp: Implemented Handle_Registry::remove().
+       * unit_tests/Test_Scheduler.cpp: Added empty aspect methods for 
verification under debugger.
+
+2007-06-23 Eric Hughes <address@hidden>
+       * ../Aspect.hpp: Base template classes to assist writing derivable 
aspects.
+       * Handle.hpp: Added aspects to Handle_Registry and Handled.  
+       * Handle.cpp: Use two hooks in Handle_Registry::add, which distinguish 
between adding a new registry entry and reusing an existing one.
+       * unit_tests/Test_Scheduler.cpp: Added test aspects for Handled and 
Handled_Registry.  They compile buit don't yet do anything.
+
+2007-06-23 Eric Hughes <address@hidden>
+       * Handle.[hc]pp: New classes for handles, handle indices to vectors, 
and handle-registered classes.
+       * unit_tests/Test_Scheduler.cpp: Unit test for handled class
+
+2007-06-22 Eric Hughes <address@hidden>
+       * Scheduler.hpp: Added second sequence number for round-robin 
scheduling of background service.
+       * Scheduler.cpp: Changed add_service to use new sequence number and 
activate_one_item to use it.
+       * Service.hpp: Renamed old Generator class; wrote new one.  Added 
shutdown method to Service.
+       * Service.cpp: Rewrote loop of Service::run to use new Generator.
+       * unit_tests/Test_Scheduler.cpp: Unit test for Service.
+       * test_support/Supplied_Service.[hc]pp: New service class with internal 
vector of prebuilt actions.
+
 2007-06-19 Eric Hughes <address@hidden>
        Added a completion check for the test listening action.
        All unit tests now fully pass.

Index: ACT/Cygnal_Instances.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/Cygnal_Instances.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- ACT/Cygnal_Instances.cpp    1 Jul 2007 10:53:50 -0000       1.3
+++ ACT/Cygnal_Instances.cpp    10 Jul 2007 14:09:08 -0000      1.4
@@ -18,7 +18,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/**    \file Cygnal_Instance.cpp
+/**    \file Cygnal_Instances.cpp
  *     \brief Template instances of Scheduling_Queue etc. needed for Cygnal.
  *
  *     Because we define the implementations of template functions outside of 
its declaration in its header,
@@ -28,10 +28,13 @@
  *     Separating definition and instantiation alleviates problems with 
multiply-defined symbols.
  */
 
+#include "Handle.cpp"
 #include "Scheduling_Queue.cpp"
+#include "Scheduler.T.cpp"
 
 namespace ACT {
-       // Explicit template instantiation.
-       template Basic_Scheduler::queue_type ;
+       // Explicit template instantiations.
+       template Basic_Scheduler< aspect::Null_Aspect_0 >::queue_type ;
+       template Basic_Scheduler< aspect::Null_Aspect_0 > ;
 
 } // end namespace ACT

Index: ACT/Scheduler.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/Scheduler.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- ACT/Scheduler.cpp   1 Jul 2007 10:53:51 -0000       1.3
+++ ACT/Scheduler.cpp   10 Jul 2007 14:09:08 -0000      1.4
@@ -37,7 +37,7 @@
                        case Task :
                                priority_category = Initial ;
                                break ;
-                       case Service :
+                       case Demon :
                                priority_category = Background ;
                                break ;
                        default :
@@ -57,123 +57,4 @@
                                ) ;
        }
 
-       //--------------------------------------------------
-       // wakeup_listener_allocated
-       //--------------------------------------------------
-       wakeup_listener_allocated::
-       wakeup_listener_allocated( size_t x, scheduler_pointer y )
-               : the_wakeup_listener( new wakeup_listener( x, y ) ) {}
-
-       //--------------------------------------------------
-       // wakeup_listener
-       //--------------------------------------------------
-       void
-       wakeup_listener::
-       operator()()
-       {
-               queue_type & the_queue = the_scheduler -> queue() ;
-               the_queue.item( permutation_index ).priority_category = 
Ordinary ;
-               the_queue.reorder( permutation_index ) ;
-       }
-
-       //--------------------------------------------------
-       // Basic_Scheduler
-       //--------------------------------------------------
-       Basic_Scheduler::
-       Basic_Scheduler()
-               : operating( true ),
-               next_sequence_number( 1 )
-       {}
-
-       //-------------------------
-       void
-       Basic_Scheduler::
-       reset()
-       {
-               operating = true ;
-       }
-
-       //-------------------------
-       void
-       Basic_Scheduler::
-       operator()()
-       {
-               while ( operating ) {
-                       activate_one_item() ;
-               }
-       }
-
-       //-------------------------
-       void
-       Basic_Scheduler::
-       operator()( unsigned int activation_bound )
-       {
-               while ( operating && activation_bound > 0 ) {
-                       -- activation_bound ;
-                       activate_one_item() ;
-               }
-       }
-
-       //-------------------------
-       void
-       Basic_Scheduler::
-       add_task( act x )
-       {
-               item_pointer item = the_queue.push( Basic_Scheduled_Item( x, ++ 
next_sequence_number ), this ) ;
-       }
-
-       void
-       Basic_Scheduler::
-       add_service( act x )
-       {
-               item_pointer item = the_queue.push( Basic_Scheduled_Item( x, ++ 
next_sequence_number, Service ), this ) ;
-       }
-
-       void
-       Basic_Scheduler::
-       add_critical_service( act )
-       {
-       }
-
-       //-------------------------
-       void
-       Basic_Scheduler::
-       activate_one_item()
-       {
-               // Note that this operation is not locked.
-               // As of this version, this is a single-threaded server.
-               if ( the_queue.empty() ) {
-                       // If the queue is finally empty, we're done.
-                       operating = false ;
-                       return ;
-                       // An alternate behavior would be to wait indefinitely 
for another scheduled item.
-                       // This is an asynchronous scheduler; it doesn't wait.
-                       // To understand how this scheduler wakes up from 
quiescence, look into service actions.
-               }
-               // Assert the_queue is not empty
-
-               queue_type::pointer item = the_queue.top_ptr() ;
-               act_state result = item -> the_action( 
the_queue.auxiliary_top() -> get() ) ;
-               if ( result == Working ) {
-                       if ( item -> action_type == Task ) {
-                               // Assert action is not a service
-                               item -> priority_category = Waiting ;
-                               the_queue.reorder( item ) ;
-                       }
-                       // Note service actions do not re-prioritize right now
-               } else {
-                       the_queue.pop() ;
-                       // Perhaps we might want to log items gone bad here.
-               }
-       }
-
-       //-------------------------
-       bool
-       Basic_Scheduler::
-       ordinary_tasks_available()
-       {
-               if ( the_queue.empty() ) return false ;
-               return the_queue.top().priority_category <= Ordinary ;
-       }
-
 } // end namespace ACT

Index: ACT/Scheduler.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/Scheduler.hpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- ACT/Scheduler.hpp   1 Jul 2007 10:53:51 -0000       1.3
+++ ACT/Scheduler.hpp   10 Jul 2007 14:09:08 -0000      1.4
@@ -25,19 +25,57 @@
 #define __Scheduler_hpp__
 
 #include "ACT.hpp"
+#include "Handle.hpp"
 #include "Scheduling_Queue.hpp"
 #include <boost/optional/optional.hpp>
-
+#include "../Aspect.hpp"
 //#include "boost/date_time/posix_time/posix_time.hpp"
 
+// Declarations within this namespace block intended for a new header file 
defining only interfaces
 namespace ACT {
+       //-------------------------
+       /**     \class Scheduler
+        *      \brief Abstract interface to scheduler.
+        */
+       class Scheduler
+               : public Handled< Scheduler >
+       {
+       public:
+               /// Add a task with bounded lifetime.
+               virtual void add_task( act ) =0 ;
+
+               /// Add a service with indefinite lifetime.
+               virtual void add_service( act ) =0 ;
 
+               ///
+               virtual bool ordinary_tasks_available() =0 ;
+
+               ///
+               Scheduler( Scheduler * that )
+                       : Handled< Scheduler >( that )
+               {} ;
+       } ;
+
+       /** \class wakeup_listener
+        *      \brief Abstract interface to a function object that wakes up a 
listener task that's waiting.
+        */
+       class wakeup_listener
+       {
+       public:
+               /// The listener body.
+               virtual void operator()() =0 ;
+
+               /// Accessor for the scheduler
+               virtual Scheduler * scheduler() const =0 ;
+       } ;
+}
+
+namespace ACT {
        //-------------------------
        /* Forward declarations for wakeup_listener
         */
        struct Basic_Scheduled_Item ;
-       class Basic_Scheduler ;
-       class wakeup_listener_allocated ;
+       template< template< class > class > class Basic_Scheduler ;
 
        //-------------------------
        /**     \class wakeup_listener_allocated
@@ -51,11 +89,12 @@
         *              this allocation strategy has no performance penalty in 
the steady state,
         *              except to the extent that excess memory usage causes 
unnecessary swapping.
         */
+       template< class S >
        class wakeup_listener_allocated
        {
        public:
                ///
-               typedef Basic_Scheduler * scheduler_pointer ;
+               typedef S * scheduler_pointer ;
                // typedef wakeup_listener::scheduler_pointer scheduler_pointer 
;
 
                ///
@@ -80,7 +119,7 @@
        } ;
 
        //-------------------------
-       /** \class wakeup_listener
+       /** \class Basic_Wakeup_Listener
         *      \brief The 'A' in ACT means 'asynchronous', so in general there 
must be a way of notifying
         *              a scheduler that an inactive ACT, one that has a 
pending sub-action, is ready to proceed.
         *      This class is the interface between a scheduler and such an ACT.
@@ -95,15 +134,17 @@
         *      The scheduler should encapsulate its own notification receiver, 
however structured,
         *              into a function object of this class, say, by binding a 
member function adapter.
         */
-       class wakeup_listener
+       template< class S >
+       class Basic_Wakeup_Listener
+               : public wakeup_listener
        {
        public:
                ///
-               typedef Basic_Scheduler * scheduler_pointer ;
+               typedef S * scheduler_pointer ;
 
        private:
                ///
-               typedef Scheduling_Queue< Basic_Scheduled_Item, 
wakeup_listener_allocated > queue_type ;
+               typedef Scheduling_Queue< Basic_Scheduled_Item, 
wakeup_listener_allocated< S > > queue_type ;
 
                /// A pointer to the item to reschedule.
                size_t permutation_index ;
@@ -119,7 +160,7 @@
                inline scheduler_pointer scheduler() const { return 
the_scheduler ; }
 
                /// Ordinary constructor used after item is within a scheduling 
queue and its storage location is known.
-               wakeup_listener( size_t x, scheduler_pointer y )
+               Basic_Wakeup_Listener( size_t x, scheduler_pointer y )
                        : permutation_index( x ), the_scheduler( y ) {}
        } ;
 
@@ -147,26 +188,35 @@
        } ;
 
        //-------------------------
-       ///
+       /** \brief Category of actions within Basic_Scheduler.
+        *              Distinguishes ordinary tasks from services, which have 
different scheduling policies.
+        */
        enum Action_Category
        {
                /// An ordinary task, executed until completed, then discarded.
                Task = 0,
 
-               /**     A service task, reset if completed, discarded if reset 
does not succeed.
+               /**     A demon task, never expected to complete, but which may 
complete.
                 *
-                *      A service executes with background priority in the 
scheduling queue.
+                *      A demon executes with background priority in the 
scheduling queue.
                 *      It may also have its own autonomous processing.
-                *      The select() call behind the wakeup listener for 
network I/O, for example, is a service.
+                *      The select() call behind the wakeup listener for 
network I/O, for example, is somewhere within a certain demon.
                 */
-               Service,
+               Demon,
 
-               /**     A critical service is one that must be run in order for 
the scheduler to run.
+               /**     A critical demon is one that must be run in order for 
the scheduler to run.
                 */
-               Critical_Service
+               Critical_Demon
        } ;
 
        //-------------------------
+       /**     \class Basic_Scheduled_Item
+        *      \brief Data within the priority queue proper.
+        *              This data is swapped during priority queue operations, 
so should remain as small as possible.
+        *
+        *      \par Future
+        *              It seems that \c the_action, which isn't needed for 
ordering, might be able to move to the auxiliary vector.
+        */
        struct Basic_Scheduled_Item
        {
                ///
@@ -189,16 +239,28 @@
        } ;
 
        //-------------------------
+       /**     \class Basic_Scheduler
+        *      \brief A basic implementation of a scheduler.
+        *
+        *      This may not be the final production version of a scheduler.
+        *      Nevertheless, a scheduler which is as simple as possible, but 
still works as a scheduler,
+        *              should be retained for testing.
+        *      In particular, this scheduler does not have a timeout mechanism 
to detect stalled actions.
+        *      This would be a defect in a production environment.
+        *      Such an absence should be retained for the test environment, to 
be able to isolate defective actions that stall.
+        */
+       template< template< class > class Aspect = aspect::Null_Aspect_0 >
        class Basic_Scheduler
+               : public Scheduler
        {
                ///
-               friend wakeup_listener ;
+               friend Basic_Wakeup_Listener< Basic_Scheduler > ;
 
                /// The type of our internal queue.
-               typedef Scheduling_Queue< Basic_Scheduled_Item, 
wakeup_listener_allocated > queue_type ;
+               typedef Scheduling_Queue< Basic_Scheduled_Item, 
wakeup_listener_allocated< Basic_Scheduler > > queue_type ;
 
                ///
-               typedef queue_type::pointer item_pointer ;
+               typedef typename queue_type::pointer item_pointer ;
 
                /// Activate the next action once.
                void activate_one_item() ;
@@ -213,11 +275,20 @@
                inline queue_type & queue() { return the_queue ; }
 
                /// Increasing sequence numbers upon scheduling implements a 
kind of LRU activation policy.
-               unsigned int next_sequence_number ;
+               unsigned int next_task_sequence_number ;
+
+               /// A separate sequence for services implements round-robin 
activation.
+               unsigned int next_service_sequence_number ;
+
+               ///
+               typedef Aspect< Basic_Scheduler > aspect_type ;
+
+               ///
+               aspect_type aspect ;
 
        public:
                /// Default constructor is private to enforce singleton
-               Basic_Scheduler() ;
+               Basic_Scheduler( aspect_type aspect = aspect_type() ) ;
 
                /// Add an ordinary task into the scheduling queue.
                void add_task( act ) ;
@@ -231,9 +302,6 @@
                /// The main execution loop.
                void operator()() ;
 
-               /// The main execution loop with an activation bound.
-               void operator()( unsigned int ) ;
-
                ///
                bool ordinary_tasks_available() ;
 
@@ -244,6 +312,39 @@
                void reset() ;
        } ;
 
+       //-------------------------
+       /** \class Basic_Scheduler_Null_Aspect
+        *      \brief Base class for aspects of \c Basic_Scheduler.
+        */
+       class Basic_Scheduler_Null_Aspect
+       {
+       public:
+               /// Guard must be true in order for execution loop to continue.
+               inline bool run_guard() { return true ; }
+
+               /// Called before any execution starts.
+               inline void run_begin() {}
+
+               /// Called after execution stops through internal means.
+               inline void run_end_ordinary() {}
+
+               /// Called if execution stop because of guard failure.
+               inline void run_end_guard_violation() {}
+       } ;
+
+       //-------------------------
 } // end namespace ACT
 
+namespace aspect {
+       //-------------------------
+       /** \brief Default null aspect for Basic_Scheduler.
+        */
+       template<>
+       class Null_Aspect_0< ACT::Basic_Scheduler< Null_Aspect_0 > >
+               : public Null_Aspect_Base< ACT::Basic_Scheduler< Null_Aspect_0 
> >,
+               public ACT::Basic_Scheduler_Null_Aspect
+       {} ;
+
+}
+
 #endif

Index: ACT/Scheduling_Queue.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/Scheduling_Queue.hpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- ACT/Scheduling_Queue.hpp    1 Jul 2007 10:53:51 -0000       1.3
+++ ACT/Scheduling_Queue.hpp    10 Jul 2007 14:09:08 -0000      1.4
@@ -76,7 +76,7 @@
 
 
        //-------------------------
-       /** \class Scheduled_Item
+       /** \class Auxiliary_Item
         *      \brief The full data that goes into the scheduling queue.
         *              It includes the underlying item plus extra housekeeping 
information.
         */
@@ -99,6 +99,9 @@
 
        //-------------------------
        /** \class Scheduled_Item_Pointer
+        *      \brief A pointer into an item within a scheduling queue.
+        *      Since items within the underlying container of a queue move 
around,
+        *              a pointer is necessary to track such motion and provide 
a stable reference for outsiders.
         */
        template< class T, class Aux >
        class Scheduled_Item_Pointer
@@ -149,7 +152,7 @@
        {
                // friends
                template< class T, class Aux > friend class 
Scheduled_Item_Pointer ;
-               friend class wakeup_listener ;
+               template< class S > friend class Basic_Wakeup_Listener ;
 
                /// The main queue for scheduled items.
                std::vector< Scheduled_Item< T > > the_queue ;

Index: ACT/Service.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/Service.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- ACT/Service.cpp     1 Jul 2007 10:53:51 -0000       1.2
+++ ACT/Service.cpp     10 Jul 2007 14:09:08 -0000      1.3
@@ -26,42 +26,53 @@
        //-------------------------
        /*      \par Implementation
         */
-       Service::
-       Service( Generator & x, Basic_Scheduler & z )
+       template< template< class > class Aspect >
+       Service< Aspect >::
+       Service( Generator & x, Scheduler & z, aspect_type aspect )
                : the_generator( x ),
-               our_scheduler( z )
-       {}
+               our_scheduler( z ),
+               aspect( aspect )
+       {
+               aspect.set_owner( this ) ;
+       }
 
        //-------------------------
        /*      \par Implementation
         */
-       act_state
-       Service::
+       template< template< class > class Aspect >
+       ACT_State
+       Service< Aspect >::
        run( wakeup_listener * w )
        {
+               aspect.log_run_begin() ;
                // We use a loop rather than a single pass because the 
generator may have multiple pending actions ready for us.
                // We'd get a similar result with just a single pass.
                // The difference is that using a single pass here would cause 
loop overhead in the scheduler.
                // It's more efficient to do ordinary cycling here.
                //
+               bool task_added( false ) ;
                while ( true ) {
-                       the_generator( w ) ;
-                       if ( the_generator.working() ) return ACT::Working ;
-                       if ( the_generator.bad() ) return set_bad() ;
-                       // Assert the_generator.completed()
-
-                       act x( the_generator.result() ) ;
+                       try {
+                               shared_ptr< basic_act > x( 
the_generator.next_action( w ) ) ;
+                               if ( ! x ) {
+                                       if ( the_generator.completed() && ! 
task_added ) {
+                                               aspect.log_run_end() ;
+                                               return set_completed() ;
+                                       } else {
+                                               aspect.log_run_end() ;
+                                               return set_ready() ; 
+                                       }
+                               }
                        our_scheduler.add_task( x ) ;
-
+                               task_added = true ;
+                       } catch ( ... ) {
+                               aspect.log_run_end() ;
+                               return set_bad() ;
+                       }
                        // If, in the future, ours scheduler might be 
unavailable for adding something new to the queue.
                        // Such unavailability would (hopefully) be temporary.
                        // It might arise, for example, from a non-blocking 
queue operation that just wasn't ready just yet.
-                       // What we would do in that case is simply to return, 
avoiding the following reset.
-                       // Upon next invocation, the result won't have changed 
and we can just try again.
-
-                       // Reset the generator and re-run the action.
-                       the_generator.reset() ;
+                       // What we would do in that case is to save our 
action-pending state and introduce at the next invocation.
                }
        }
-
 }

Index: ACT/Service.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/Service.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- ACT/Service.hpp     1 Jul 2007 10:53:51 -0000       1.2
+++ ACT/Service.hpp     10 Jul 2007 14:09:08 -0000      1.3
@@ -18,7 +18,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/// \file Server.hpp
+/// \file Service.hpp
 
 #pragma once
 #ifndef __Service_hpp__
@@ -26,9 +26,12 @@
 
 #include "ACT.hpp"
 #include "Scheduler.hpp"
+#include "Aspect.hpp"
 
 namespace ACT {
-       class Generator
+       //-------------------------
+       /// \brief still used in IO, for now.
+       class Obsolete_Generator
                : public ACT::autonomous_act
        {
        public:
@@ -39,6 +42,59 @@
        } ;
 
        //-------------------------
+       /**     \class Generator
+        *      \brief A generator of actions, in bursts, used to feed a 
Service.
+        *              This class is a base for service implementations.
+        *
+        */
+       class Generator
+       {
+       public:
+               /**     The parameter is necessary for when a Service must 
suspend itself waiting for external events.
+                *      The central example is a socket listener, which 
generates new connections, each encapsulated in a protocol behavior.
+                *
+                *      \post
+                *      - return is zero implies no more action is available at 
the present time.  Ask again later.
+                */
+               virtual shared_ptr< basic_act > next_action( wakeup_listener * 
) =0 ;
+
+               /**
+                *      \post
+                *      - return is true 
+                *                      implies return value of next_action 
will always be zero
+                *              and     implies return value of completed will 
always be true
+                */
+               virtual bool completed() { return false ; }
+
+               /** The meaning of this shut-down routine are weak and lazy, 
rather than strong and immediate.
+                *      The only requirement is that the number of ready 
actions monotonically decrease with each call to \c next_action.
+                *      Conceptually, there must be a counter of ready actions.
+                *      It must decrease this count by at least one with each 
call to \c next_action.
+                *
+                *      These ready actions may be implicit or explicit.
+                *      Explicit action are those, say, waiting in a queue, 
already constructed and ready to go.
+                *      Generically, all generators will contain these kind of 
explict actions.
+                *
+                *      A central example of an implicit action is the set of 
pending connections on a listening socket.
+                *      The OS has established a connection, so there's some 
potential action on that connection.
+                *      Whatever that action is matter nothing to this base 
class.
+                *      What does matter is that after shutdown, that the 
listening socket be closed, 
+                *              or at least put in a state to reject 
connections, thereby not generating any new actions.
+                *
+                *      The weak requirement of this shutdown does not preclude 
immediate termination.
+                *      The requirement is that the count of available actions 
decrease by at least one, not by exactly one.
+                *      A service that wishes to hang up immediately, simply 
ending, may do so.
+                *      Indeed, a particular implementation class might well 
have configurable shutdown behavior,
+                *              depending on whether the desired shutdown is 
graceful or abrupt.
+                *
+                *      Implementing classes should document their approach to 
shutdown.
+                *      This will avoid incorrect expectations about behavior,
+                *              which expectations might develop out of habit 
or idiom, rather than out of requirement.
+                */
+               virtual void shutdown() =0 ;
+       } ;
+
+       //-------------------------
        /**     \class Service
         *      \brief A service is a persistent action whose result to create 
new actions and to schedule them for execution.
         *
@@ -51,22 +107,61 @@
         *      
         *      A service, in addition, is "always working".
         *      It only completes when it needs to shut down, either from an 
internal failure or by external command.
+        *
+        *      WARNING: A service must not both schedule a new action and 
return \c Completed in the same activation.
+        *      This restriction simplifies implementation of the scheduler, 
which then doesn't need to removed
+        *              a completed service action from within the middle of 
the scheduling queue.
+        *      When a service schedules no new actions, it remains at the top 
of the priority queue,
+        *              from where it can be removed like any other task.
         */
+       template< template< class > class Aspect = aspect::Null_Aspect_0 >
        class Service 
                : public autonomous_act
        {
-               Basic_Scheduler & our_scheduler ;
+       public:
+               typedef Aspect< Service > aspect_type ;
+
+       private:
+               /// Aspect instance.
+               aspect_type aspect ;
+
+               Scheduler & our_scheduler ;
 
                Generator & the_generator ;
        public:
                /// 
-               Service( Generator & x, Basic_Scheduler & z ) ;
+               Service( Generator & x, Scheduler & z, aspect_type aspect = 
aspect_type() ) ;
+
+               ///
+               ACT_State run( wakeup_listener * ) ;
 
                ///
-               act_state run( wakeup_listener * ) ;
+               inline void shutdown() { the_generator.shutdown() ; }
+       } ;
+
+       //-------------------------
+       /**     \class Service_Null_Aspect
+        *      \brief Null aspect for \c Service
+        */
+       class Service_Null_Aspect
+       {
+       public:
+               void log_run_begin() {} ;
+               void log_run_end() {} ;
        } ;
 
        //-------------------------
 } // end namespace ACT
 
+namespace aspect {
+       //-------------------------
+       /**     \brief Default null aspect for \c Service.
+        */
+       template<>
+       class Null_Aspect_0< ACT::Service< Null_Aspect_0 > >
+               : public ACT::Service_Null_Aspect,
+               public Null_Aspect_Base< ACT::Service< Null_Aspect_0 > >
+       {} ;
+}
+
 #endif
\ No newline at end of file

Index: ACT/test_support/Action_Tracing.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/test_support/Action_Tracing.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- ACT/test_support/Action_Tracing.hpp 1 Jul 2007 10:53:51 -0000       1.2
+++ ACT/test_support/Action_Tracing.hpp 10 Jul 2007 14:09:09 -0000      1.3
@@ -30,6 +30,7 @@
 
        //-------------------------
        /** \class execution_trace
+        *      \brief A wrapper around a string to hold a logging trace of an 
execution pathway.
         */
        class execution_trace
        {

Index: ACT/test_support/Listening_Actions.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/test_support/Listening_Actions.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- ACT/test_support/Listening_Actions.cpp      1 Jul 2007 10:53:51 -0000       
1.3
+++ ACT/test_support/Listening_Actions.cpp      10 Jul 2007 14:09:09 -0000      
1.4
@@ -24,53 +24,33 @@
 #include "Listening_Actions.hpp"
 #include "ACT/Scheduler.hpp"
 
+// Required to obtain instantiation of template base classes
+#include "ACT/Listen.T.cpp"
+
 namespace ACT {
        //--------------------------------------------------
        // N_to_completion_Monitor
        //--------------------------------------------------
-       std::vector< wakeup_listener::scheduler_pointer > 
N_to_completion_Monitor::schedulers ;
-
-       N_to_completion_Monitor::
-       N_to_completion_Monitor()
-               : listeners( 0 )
-       {}
-
        void
        N_to_completion_Monitor::
        add_wakeup_item( N_to_completion *, wakeup_listener * w )
        {
-               // Assert this instance is registered in the scheduler and will 
eventually run.
-               // Note: as of this writing, there's no way for an object to 
register itself with the scheduler.
-               //              Some other object must do so.
-               //              It's not yet clear whether this is good or not.
-
-               //      We ignore the N_to_completion pointer, since in this 
test action,
+               //      We ignore the N_to_completion pointer, since, for the 
purposes of the present test action,
                //              we consider any background action always ready 
for wakeup after one cycle of quiescence.
-               listeners.push_back( w ) ;
+
+               Parent::add_ready_listener_task( w ) ;
        }
 
-       act_state
+       ACT_State
        N_to_completion_Monitor::
        run()
        {
-               if ( listeners.empty() ) {
-                       // This monitor is no longer necessary, since there's 
nothing to wake up.
-                       // Therefore we return complete and let the scheduler 
remove this instance.
-                       return Completed ;
-               }
-               while ( ! listeners.empty() ) {
-                       ( * listeners.back() )() ;
-                       listeners.pop_back() ;
-               }
-               return Working ;
+               return Parent::wake_up_ready_tasks() ;
        }
 
        //--------------------------------------------------
        // N_to_completion
        //--------------------------------------------------
-       boost::shared_ptr< N_to_completion_Monitor > 
N_to_completion::the_monitor ;
-
-       //-------------------------
        N_to_completion::
        N_to_completion( unsigned int n, tracking_function * f )
                : total_number_of_activations( n ),
@@ -79,7 +59,7 @@
        {}
 
        //-------------------------
-       act_state
+       ACT_State
        N_to_completion::
        run( wakeup_listener * w )
        {
@@ -88,8 +68,8 @@
                if ( number_of_activations_left == 0 ) return set_completed() ;
                // Assert we're not done yet.
                // Register with our monitor before returning.
-               register_for_wakeup( w ) ;
-               return Working ;
+               register_for_wakeup( this, w ) ;
+               return set_would_block() ; ;
        }
 
        //-------------------------
@@ -98,22 +78,15 @@
        reset()
        {
                number_of_activations_left = total_number_of_activations ;
-               set_working() ;
-       }
-
-       //-------------------------
-       void
-       N_to_completion::
-       register_for_wakeup( wakeup_listener * w )
-       {
-               if ( w == 0 ) return ;
-               if ( the_monitor.get() == 0 ) {
-                       the_monitor = shared_ptr< monitor_type >( new 
monitor_type() ) ;
-                       w -> scheduler() -> add_service( act( the_monitor ) ) ;
-               }
-               // Assert monitor exists
-               the_monitor -> add_wakeup_item( this, w ) ;
+               set_ready() ;
        }
 
        //-------------------------
 } // end namespace ACT
+
+//-------------------------
+// Instantiate an instance of Handle_Registry_Follower as needed for 
N_to_Completion
+#include "ACT/Handle.cpp"
+namespace ACT {
+       template Handle_Registry_Follower< shared_ptr< N_to_completion_Monitor 
>, Scheduler > ;
+}
\ No newline at end of file

Index: ACT/test_support/Listening_Actions.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/test_support/Listening_Actions.hpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- ACT/test_support/Listening_Actions.hpp      1 Jul 2007 10:53:51 -0000       
1.3
+++ ACT/test_support/Listening_Actions.hpp      10 Jul 2007 14:09:09 -0000      
1.4
@@ -24,36 +24,34 @@
 #ifndef __Listening_Actions_hpp__
 #define __Listening_Actions_hpp__
 
-#include "ACT/Scheduler.hpp"
+#include "ACT/Listen.hpp"
 #include "Action_Tracing.hpp"
-#include <boost/optional.hpp>
-#include <vector>
 
 namespace ACT {
-       // Forward declaration
+       // Forward
        class N_to_completion ;
 
        //-------------------------
        /**     \class N_to_completion_Monitor
         *      \brief A monitor for N_to_completion.
+        *
+        *      Note that this class derives from \c simple_act, rather than \c 
autonomous_act.
+        *      The monitor that wakes up other actions does not itself sleep.
         */
        class N_to_completion_Monitor
-               : public simple_act
+               : public Basic_Listen_Monitor< N_to_completion >
        {
-               /// A vector of schedulers
-               static std::vector< wakeup_listener::scheduler_pointer > 
schedulers ;
+               /// Type of parent monitor class, called often in implementation
+               typedef Basic_Listen_Monitor< N_to_completion > Parent ;
 
-               std::vector< wakeup_listener * > listeners ;
-
-               act_state run() ;
+               /// Action body
+               ACT_State run() ;
 
        public:
                /// Default constructor.
-               N_to_completion_Monitor() ;
-
-               /// Query whether there are any actions registered for wakeup.
-               inline bool empty() { return listeners.empty() ; }
+               N_to_completion_Monitor() {} ;
 
+               /// Implementation of specific wake-up preparation
                void add_wakeup_item( N_to_completion *, wakeup_listener * ) ;
        } ;
 
@@ -62,14 +60,8 @@
         *      \brief Action that completes after N activations.
         */
        class N_to_completion
-               : public autonomous_act
+               : public Basic_Listening_Task< N_to_completion, 
N_to_completion_Monitor >
        {
-               /// The monitor type for these actions to register with.
-               typedef N_to_completion_Monitor monitor_type ;
-
-               ///
-               static shared_ptr< monitor_type > the_monitor ;
-
                /// Tracking
                std::auto_ptr< tracking_function > tracker ;
 
@@ -80,19 +72,16 @@
                unsigned int total_number_of_activations ;
 
                /// Action body, proxied by operator()
-               act_state run( wakeup_listener * ) ;
-
-               /// Register an action for wakeup
-               void register_for_wakeup( wakeup_listener * ) ;
+               ACT_State run( wakeup_listener * ) ;
 
        public:
                ///
                N_to_completion( unsigned int n, tracking_function * = 0 ) ;
 
                void reset() ;
-
        } ;
 
+       //-------------------------
 } // end namespace ACT
 
 #endif

Index: ACT/test_support/Simple_Actions.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/test_support/Simple_Actions.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- ACT/test_support/Simple_Actions.cpp 1 Jul 2007 10:53:52 -0000       1.2
+++ ACT/test_support/Simple_Actions.cpp 10 Jul 2007 14:09:09 -0000      1.3
@@ -27,7 +27,7 @@
        //--------------------------------------------------
        // simple_action
        //--------------------------------------------------
-       act_state
+       ACT_State
        single_action::
        run()
        {
@@ -38,12 +38,12 @@
        //--------------------------------------------------
        // no_action
        //--------------------------------------------------
-       act_state
+       ACT_State
        no_action::
        run()
        {
                if ( tracker.get() != 0 ) ( * tracker )( "" ) ;
-               return Completed ;
+               return set_completed() ;
        }
 
 } // end namespace ACT

Index: ACT/test_support/Simple_Actions.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/test_support/Simple_Actions.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- ACT/test_support/Simple_Actions.hpp 1 Jul 2007 10:53:52 -0000       1.2
+++ ACT/test_support/Simple_Actions.hpp 10 Jul 2007 14:09:09 -0000      1.3
@@ -28,35 +28,10 @@
 #include "Action_Tracing.hpp"
 
 namespace ACT {
-       //-------------------------
-       /**     \class N_to_completion
-        *      \brief Action that completes after N activations.
-        */
-       class N_to_completion
-               : public autonomous_act
-       {
-               /// Tracking
-               std::auto_ptr< tracking_function > tracker ;
-
-               ///
-               unsigned int number_of_activations_left ;
-
-               ///
-               unsigned int total_number_of_activations ;
-
-               ///
-               act_state run( wakeup_listener * ) ;
-
-       public:
-               ///
-               N_to_completion( unsigned int n, tracking_function * = 0 ) ;
-
-               void reset() ;
-
-       } ;
 
        //-------------------------
        /**     \class single_action
+        *      \brief An action that always completes at its first activation.
         */
        class single_action
                : public simple_act
@@ -65,7 +40,7 @@
                std::auto_ptr< tracking_function > tracker ;
 
                /// Action body
-               act_state run() ;
+               ACT_State run() ;
        public:
                ///
                single_action( tracking_function * x = 0 )
@@ -88,7 +63,7 @@
                std::auto_ptr< tracking_function > tracker ;
 
                /// Action body does very little.
-               act_state run() ;
+               ACT_State run() ;
 
        public:
                /// Ordinary constructor.

Index: ACT/unit_tests/Test_ACT.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/unit_tests/Test_ACT.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- ACT/unit_tests/Test_ACT.cpp 1 Jul 2007 10:53:52 -0000       1.2
+++ ACT/unit_tests/Test_ACT.cpp 10 Jul 2007 14:09:09 -0000      1.3
@@ -26,6 +26,7 @@
 
 #include "../ACT.hpp"
 #include "ACT/test_support/Simple_Actions.hpp"
+#include "ACT/test_support/Listening_Actions.hpp"
 
 using namespace ACT ;
 
@@ -47,17 +48,17 @@
                : number_of_calls( 0 )
        {} ;
 
-       act_state run( wakeup_listener * ) 
+       ACT_State run( wakeup_listener * ) 
        {
                switch ( number_of_calls ) {
                        case 0 :
                                number_of_calls = 1 ;
-                               return ACT::Working ;
+                               return internal_state() ;
                        case 1 :
                                number_of_calls = 2 ;
                                return set_completed() ;
-                       case 2 :
-                               return ACT::Completed ;
+                       // Note:
+                       // case 2 should never be called, since the guard for 
calling run requires that the action still be working
                }
                throw std::exception( "Not Reached" ) ;
        }

Index: ACT/unit_tests/Test_Scheduler.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/unit_tests/Test_Scheduler.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- ACT/unit_tests/Test_Scheduler.cpp   1 Jul 2007 10:53:52 -0000       1.3
+++ ACT/unit_tests/Test_Scheduler.cpp   10 Jul 2007 14:09:09 -0000      1.4
@@ -24,14 +24,250 @@
 #include <boost/test/auto_unit_test.hpp>
 #include <boost/test/test_tools.hpp>
 
-#include "ACT/test_support/Simple_Actions.hpp"
 #include "ACT/Scheduler.hpp"
+#include "ACT/test_support/Simple_Actions.hpp"
+#include "ACT/test_support/Listening_Actions.hpp"
+#include "ACT/test_support/Supplied_Service.hpp"
+#include "ACT/Pause_Demon.hpp"
+
+// Include implementations for explicit instantiation.
+#include "ACT/Handle.cpp"
+#include "ACT/Scheduler.T.cpp"
+#include "ACT/Scheduling_Queue.cpp"
+
+namespace ACT_Test {
+       //--------------------------------------------------
+       // White box test of Handle using aspects.
+       //--------------------------------------------------
+       using namespace ACT ;
+
+       //---------------
+       // This is the template definition of the base aspect class.
+       // Specializations of this class provide the actual aspect classes 
compiled in to the classes under test.
+
+       /// \brief Generic template declaration to be specialized for 
particular class aspects.
+       template< class, class > class test_aspect {} ;
+       /// \brief Generic template declaration to be specialized for 
particular class aspects.
+       template< class, class, class > class test_aspect_2 {} ;
+
+       //---------------
+       /// \brief Test aspect for Handle_Registry_Leader
+       template< class T >
+       class test_aspect< T, Handle_Registry_Leader< T, test_aspect > >
+               : public aspect::Null_Aspect_1< T, Handle_Registry_Leader< T, 
aspect::Null_Aspect_1 > >
+       {
+               // We need the execution trace in this class because it's 
constructed statically.
+               // If we had two static classes that required a common trace, 
we'd have to use a third class, a singleton, to put this in.
+               execution_trace tr ;
 
-using namespace ACT ;
+       public:
+               execution_trace & trace() { return tr ; }
+               std::string result() const { return tr.result() ; }
+
+               void add_in_new_place() { tr.add( "N" ) ; }
+               void add_in_old_place() { tr.add( "O" ) ; }
+       } ;
+
+       //---------------
+       /// \brief Test aspect for Handle_Registry_Follower.
+       template< class T, class Leader >
+       class test_aspect_2< T, Leader, Handle_Registry_Follower< T, Leader, 
test_aspect_2 > >
+               : public aspect::Null_Aspect_2< T, Leader, 
Handle_Registry_Follower< T, Leader, aspect::Null_Aspect_2 > >
+       {
+               // See reason above for why the execution trace is here
+               execution_trace tr ;
+       public:
+               execution_trace & trace() { return tr ; }
+               std::string result() const { return tr.result() ; }
+
+               void access_from_existing_slot() { tr.add( "A" ) ; }
+               void enlarge_size_of_vector() { tr.add( "X" ) ; }
+       } ;
+
+       //---------------
+       // Forward
+       class test ;
+       //---------------
+       /// \brief Test aspect for Handled.
+       template< class T >
+       class test_aspect< T, Handled< T, test_aspect > >
+               : public Null_Aspect_Handled< T >,
+               public aspect::Aspect_Has_Access_To_Owner< Handled< T, 
test_aspect > >
+       {
+               // The explicit namespace qualification distinguishes the 
generic declaration from this specialization.
+               typedef Handled< test, ACT_Test::test_aspect > owner_type ;
+
+       public:
+               std::string result() const { return owner() -> 
our_registry.aspect.result() ; }
+       } ;
+
+       //---------------
+       /// \brief A test class for \c Handled, deriving from it in order to 
exercise it.
+       class test
+               : public Handled< test, test_aspect >
+       {
+               typedef Handled< test, test_aspect > Handled_Base ;
+       public:
+               test() : Handled_Base( this ) {}
+
+               std::string result() const { return aspect.result() ; }
+       } ;
+
+       //---------------
+       BOOST_AUTO_UNIT_TEST( handle_one )
+       {
+               // We declare variables within blocks to invoke their 
destructors.
+               {
+                       test x ;
+                       BOOST_CHECK( test::registry_at( x.handle() ) == & x ) ;
+                       BOOST_CHECK( x.result() == "N" ) ;
+               }
+               // The second time, there should be an existing entry in the 
free list to allocate from
+               {
+                       test x ;
+                       BOOST_CHECK( test::registry_at( x.handle() ) == & x ) ;
+                       BOOST_CHECK( x.result() == "NO" ) ;
+               }
+               {
+                       test x ;
+                       BOOST_CHECK( test::registry_at( x.handle() ) == & x ) ;
+                       BOOST_CHECK( x.result() == "NOO" ) ;
+                       // Another object after the previous test.
+                       test y ;
+                       BOOST_CHECK( test::registry_at( y.handle() ) == & y ) ;
+                       BOOST_CHECK( y.result() == "NOON" ) ;
+                       // Since the execution trace should be in a common 
class registry, results from both objects should match.
+                       BOOST_CHECK( y.result() == x.result() ) ;
+               }
+       }
+
+       //---------------
+       BOOST_AUTO_UNIT_TEST( handle_two )
+       {
+               test x ;
+               Handle_Registry_Follower< int, test, test_aspect_2 > follower ;
+               std::string found( follower.aspect.result() ) ;
+               std::string expected( "" ) ;
+               BOOST_CHECK( found == "" ) ;
+
+               follower[ x.handle() ] = 1 ;
+               found = follower.aspect.result() ;
+               expected = "XA" ;               // Expand follower registry, 
then add
+               BOOST_CHECK_MESSAGE( found == expected,
+                       "Found result " << found << ". Expected result " << 
expected << "." ) ;
+
+               test y ;
+               follower[ y.handle() ] = 2 ;
+               found = follower.aspect.result() ;
+               expected = "XAXA" ;             // Expand again, then add
+               BOOST_CHECK_MESSAGE( found == expected,
+                       "Found result " << found << ". Expected result " << 
expected << "." ) ;
+
+               x.~test() ;             // invoke destructor to free up 
existing handle
+               test z ;                // should issue the handle that 'x' had.
+               follower[ z.handle() ] = 3 ;
+               found = follower.aspect.result() ;
+               expected = "XAXAA" ;            // No expansion this time, just 
add
+               BOOST_CHECK_MESSAGE( found == expected,
+                       "Found result " << found << ". Expected result " << 
expected << "." ) ;
+       }
+
+       //--------------------------------------------------
+       // Basic exercises for the scheduler.
+       //--------------------------------------------------
+
+       /// \brief Body of test aspect for \c Basic_Scheduler; aspect itself is 
a pointer to this class.
+       class scheduler_aspect_body
+       {
+               size_t execution_count ;
+               size_t execution_bound ;
+       public:
+               scheduler_aspect_body()
+                       : execution_bound( 0 ) {}
+
+               void run_begin() { execution_count = 0 ; }
+
+               bool run_guard()
+               {
+                       if ( execution_count >= execution_bound ) return false ;
+                       ++ execution_count ;
+                       return true ;
+               }
+
+               void set_execution_bound( size_t n ) { execution_bound = n ; }
+
+               bool finished_within_bound() { return execution_count <= 
execution_bound ; }
+
+               bool finished_at_bound() { return execution_count == 
execution_bound ; }
+
+       } ;
+
+       template< class Owner > class scheduler_aspect ;
+
+       /// \brief test aspect for \c Basic_Scheduler
+       template<>
+       class scheduler_aspect< Basic_Scheduler< scheduler_aspect > >
+               : public Basic_Scheduler_Null_Aspect,
+               public aspect::Aspect_Has_Access_To_Owner< Basic_Scheduler< 
scheduler_aspect > >
+       {
+               scheduler_aspect_body * body ;
+
+       public:
+               scheduler_aspect()
+                       : body( 0 ) {}
+
+               scheduler_aspect( scheduler_aspect_body * b )
+                       : body( b ) {}
+
+               void run_begin() { if ( body ) body -> run_begin() ; }
+
+               bool run_guard() { return ( body ) ? body -> run_guard() : true 
; }
+
+               void set_execution_bound( size_t n ) { if ( body ) body -> 
set_execution_bound( n ) ; }
+
+               bool finished_within_bound() { return ( body ) ? body -> 
finished_within_bound() : false ; }
+
+               bool finished_at_bound() { return ( body ) ? body -> 
finished_at_bound() : false ; }
+
+       } ;
+
+       typedef scheduler_aspect< Basic_Scheduler< scheduler_aspect > > 
Test_Scheduler_Aspect ;
+       typedef Basic_Scheduler< scheduler_aspect > Test_Scheduler ;
+
+       // Explicit instantiation of our Test_Scheduler
+       template Test_Scheduler ;
+
+       //--------------------------------------------------
+       // This test checks that the execution guard functions correctly to 
limit the total number of execution passes.
+       BOOST_AUTO_UNIT_TEST( guard_functions )
+       {
+               scheduler_aspect_body a ;
+               Test_Scheduler b = Test_Scheduler( Test_Scheduler_Aspect( & a ) 
) ;
+
+               /* N_to_completion( k ) causes the execution of '2k' actions:
+                *      - 'k' actions of the N_to_completion task
+                *      - 'k' actions of the listening monitor service.
+                * N_to_completion( 6 ) causes 12 action invocations.
+                * We run them 4 at a time.
+                * After the last one, the queue should be empty.
+                */
+               b.add_task( act( new N_to_completion( 6, 0 ) ) ) ;
+               a.set_execution_bound( 4 ) ;
+               b() ;
+               BOOST_CHECK( a.finished_within_bound() ) ;
+               BOOST_CHECK( ! b.empty() ) ;
+               b() ;
+               BOOST_CHECK( a.finished_within_bound() ) ;
+               BOOST_CHECK( ! b.empty() ) ;
+               b() ;
+               BOOST_CHECK( a.finished_at_bound() ) ;
+               BOOST_CHECK( b.empty() ) ;
+       }
 
-BOOST_AUTO_UNIT_TEST( null )
-{
-       Basic_Scheduler b ;
+       BOOST_AUTO_UNIT_TEST( some_single_actions )
+       {
+               scheduler_aspect_body a ;
+               Test_Scheduler b = Test_Scheduler( Test_Scheduler_Aspect( & a ) 
) ;
 
        execution_trace tr ;
        b.add_task( act( new no_action( new simple_tracker( tr, "N" ) ) ) ) ;
@@ -39,40 +275,75 @@
        b.add_task( act( new single_action( new simple_tracker( tr, "B" ) ) ) ) 
;
        b.add_task( act( new single_action( new simple_tracker( tr, "C" ) ) ) ) 
;
 
-       b( 100 ) ;
+               a.set_execution_bound( 100 ) ;
+               b() ;
        std::string expected( "ABC" ) ;
        BOOST_CHECK_MESSAGE( tr.result() == expected,
                "Found result " << tr.result() << ". Expected result " << 
expected << "." ) ;
+               BOOST_CHECK( a.finished_within_bound() ) ;
        BOOST_CHECK( b.empty() ) ;
-}
+       }
 
-BOOST_AUTO_UNIT_TEST( act_n_interleaved )
-{
-       Basic_Scheduler b ;
-       BOOST_REQUIRE( b.empty() ) ;
+       BOOST_AUTO_UNIT_TEST( act_n_interleaved )
+       {
+               scheduler_aspect_body a ;
+               Test_Scheduler b = Test_Scheduler( Test_Scheduler_Aspect( & a ) 
) ;
 
        execution_trace tr ;
        b.add_task( act( new N_to_completion( 2, new simple_tracker( tr, "A" ) 
) ) ) ;
        b.add_task( act( new N_to_completion( 3, new simple_tracker( tr, "B" ) 
) ) ) ;
        b.add_task( act( new N_to_completion( 5, new simple_tracker( tr, "C" ) 
) ) ) ;
        
-       b( 100 ) ;
+               a.set_execution_bound( 100 ) ;
+               b() ;
        std::string expected( "ABCABCBCCC" ) ;
        BOOST_CHECK_MESSAGE( tr.result() == expected,
                "Found result " << tr.result() << ". Expected result " << 
expected << "." ) ;
        BOOST_CHECK( b.empty() ) ;
-}
+       }
 
-//--------------------------------------------------
-#include "ACT/Pause_Service.hpp"
+       //--------------------------------------------------
+       // Same as act_n_interleaved, but using a Supplied_Service
 
-BOOST_AUTO_UNIT_TEST( pause_action )
-{
-       Basic_Scheduler b ;
+       BOOST_AUTO_UNIT_TEST( act_n_service )
+       {
+               scheduler_aspect_body a ;
+               Test_Scheduler b = Test_Scheduler( Test_Scheduler_Aspect( & a ) 
) ;
+
+               execution_trace tr ;
+               Supplied_Service * ss = new Supplied_Service( b, new 
simple_tracker( tr, "S" ) ) ;
+               ss -> add_task( shared_ptr< basic_act >( new N_to_completion( 
2, new simple_tracker( tr, "A" ) ) ) ) ;
+               ss -> add_task( shared_ptr< basic_act >( new N_to_completion( 
3, new simple_tracker( tr, "B" ) ) ) ) ;
+               ss -> add_task( shared_ptr< basic_act >( new N_to_completion( 
5, new simple_tracker( tr, "C" ) ) ) ) ;
+
+               b.add_service( act( ss ) ) ;
+               ss -> shutdown() ;
+               a.set_execution_bound( 100 ) ;
+               b() ;
+               // First "S" is to enter the new tasks into the queue.
+               // Second "S" is to allow the service to return Completed and 
leave the scheduling queue.
+               std::string expected( "SABCSABCBCCC" ) ;
+               BOOST_CHECK_MESSAGE( tr.result() == expected,
+                       "Found result " << tr.result() << ". Expected result " 
<< expected << "." ) ;
+       }
+
+       //--------------------------------------------------
+       BOOST_AUTO_UNIT_TEST( pause_action )
+       {
+               scheduler_aspect_body a ;
+               Test_Scheduler b = Test_Scheduler( Test_Scheduler_Aspect( & a ) 
) ;
        BOOST_REQUIRE( b.empty() ) ;
 
-       Pause_Service x( & b ) ;
+               Pause_Demon * pause( new Pause_Demon( & b ) ) ;
        b.add_task( act( new no_action( 0 ) ) ) ;
-       x() ;
-}
+               // This pause action should immediately return, because there's 
a pending action in the scheduler.
+               ( * pause )() ;
+
+               a.set_execution_bound( 2 ) ;
+               b.add_service( act( pause ) ) ;
+               b() ;
+               BOOST_CHECK( a.finished_at_bound() ) ;  // Pause demon should 
execute once, no_action once.
+               BOOST_CHECK( ! b.empty() ) ;                    // demon should 
still be in queue.
+       }
 
+} // end namespace ACT_test
\ No newline at end of file

Index: ACT/unit_tests/Test_Scheduling_Queue.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/ACT/unit_tests/Test_Scheduling_Queue.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- ACT/unit_tests/Test_Scheduling_Queue.cpp    1 Jul 2007 10:53:52 -0000       
1.3
+++ ACT/unit_tests/Test_Scheduling_Queue.cpp    10 Jul 2007 14:09:09 -0000      
1.4
@@ -27,8 +27,6 @@
 #include "unit_tests/Permutation.hpp"
 #include "unit_tests/Random_Permutation.hpp"
 
-// Include this implementation file in order to instantiate template
-#include "ACT/Scheduling_Queue.cpp"
 
 /** A test item to put into a scheduling queue.
  */
@@ -45,9 +43,12 @@
 } ;
 
 // Explicit instantiation
-template ACT::Scheduling_Queue< test_item, ACT::wakeup_listener_allocated > ;
+#include "ACT/Scheduling_Queue.cpp"
+#include "ACT/Scheduler.T.cpp"
+template ACT::wakeup_listener_allocated< ACT::Basic_Scheduler<> > ;
+template ACT::Scheduling_Queue< test_item, ACT::wakeup_listener_allocated< 
ACT::Basic_Scheduler<> > > ;
 
-typedef ACT::Scheduling_Queue< test_item, ACT::wakeup_listener_allocated > 
queue_type ;
+typedef ACT::Scheduling_Queue< test_item, ACT::wakeup_listener_allocated< 
ACT::Basic_Scheduler<> > > queue_type ;
 typedef queue_type::pointer pointer ;
 
 using namespace ACT ;

Index: HTTP/HTTP_Behavior.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/HTTP/HTTP_Behavior.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- HTTP/HTTP_Behavior.cpp      1 Jul 2007 10:53:52 -0000       1.2
+++ HTTP/HTTP_Behavior.cpp      10 Jul 2007 14:09:09 -0000      1.3
@@ -33,11 +33,11 @@
        {}
 
        //-------------------------
-       act_state
+       ACT::ACT_State
        HTTP_Behavior::
        run( wakeup_listener * w )
        {
-               act_state x ;
+               ACT::ACT_State x( ACT::ACT_State::Ready ) ;
 
                switch ( protocol_state ) {
                        case initial:
@@ -45,8 +45,8 @@
                                protocol_state = scanning_request ;
                        case scanning_request:
                                x = scan_request( w ) ;
-                               if ( x == Bad ) return set_bad() ;
-                               if ( x == Working ) return Working ;
+                               if ( x.bad() ) return set_bad() ;
+                               if ( x.working() ) return set_state( x ) ;
                                protocol_state = responding ;
                        case responding:
                                // We'll support HTTP/1.0 later.
@@ -71,11 +71,11 @@
                                protocol_state = sending_final_message ;
                        case sending_final_message:
                                x = the_device -> Sink::operator()( w ) ;
-                               if ( x == Bad ) return set_bad() ;
-                               if ( x == Working ) return Working ;
+                               if ( x.bad() ) return set_bad() ;
+                               if ( x.working() ) return set_state( x ) ;
                                return set_completed() ;
                } ;
-               return ACT::Working ;
+               return set_would_block() ;
        }
 
 } } // end namespace cygnal::HTTP

Index: HTTP/HTTP_Behavior.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/HTTP/HTTP_Behavior.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- HTTP/HTTP_Behavior.hpp      1 Jul 2007 10:53:52 -0000       1.2
+++ HTTP/HTTP_Behavior.hpp      10 Jul 2007 14:09:09 -0000      1.3
@@ -57,7 +57,7 @@
                HTTP_Behavior( IO::Device * ) ;
 
                /// 
-               ACT::act_state run( ACT::wakeup_listener * ) ;
+               ACT::ACT_State run( ACT::wakeup_listener * ) ;
 
                ///
                static shared_ptr< ACT::autonomous_act > new_HTTP_Behavior( 
IO::Device * ) ;

Index: HTTP/HTTP_Parse.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/HTTP/HTTP_Parse.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- HTTP/HTTP_Parse.cpp 1 Jul 2007 10:53:52 -0000       1.2
+++ HTTP/HTTP_Parse.cpp 10 Jul 2007 14:09:09 -0000      1.3
@@ -163,7 +163,7 @@
        {}
 
        //-------------------------
-       ACT::act_state
+       ACT::ACT_State
        read_single_header::
        scan( ACT::wakeup_listener * w )
        {
@@ -289,7 +289,7 @@
                // Assert n_left_to_process == 0 
 
                end_of_processing_loop:
-               return ACT::Working ;
+               return source_state() ;
        }
 
        //-------------------------
@@ -312,7 +312,7 @@
                message_header_size = 0 ;
                r_field_name.set_begin( next_character ) ;
                r_field_name.set_length( 0 ) ;
-               set_working() ;
+               set_ready() ;
        }
 
        //--------------------------------------------------
@@ -327,7 +327,7 @@
        {} ;
 
        //-------------------------
-       ACT::act_state
+       ACT::ACT_State
        read_message_headers_action::
        scan( ACT::wakeup_listener * waken )
        {
@@ -342,7 +342,7 @@
                                        // Our subroutine went bad.  So do we.
                                        return set_bad() ;
                                }
-                               return ACT::Working ;
+                               return source_state() ;
                        }
                        // Assert (postcondition--read_single_header action 
completed) input processed was "message-header? CR LF"
                        IO::buffer field_name( 
read_single_header_action.result_field_name() ) ;
@@ -395,7 +395,7 @@
        }
 
        //-------------------------
-       ACT::act_state
+       ACT::ACT_State
        Request_Method_Scanner::
        scan( ACT::wakeup_listener * w )
        {
@@ -451,34 +451,34 @@
        /**     \par Implementation Notes
         *      - The protocol designator "HTTP" is sensitive to case.
         */
-       ACT::act_state
+       ACT::ACT_State
        Request_Version_Scanner::
        scan( ACT::wakeup_listener * w )
        {
                char ch ;
                switch ( scan_state ) {
                        case initial:
-                               if ( n_left_to_process == 0 ) { scan_state = 
initial ; return Working ; }
+                               if ( n_left_to_process == 0 ) { scan_state = 
initial ; return source_state() ; }
                                ch = * next_character ++ ; -- n_left_to_process 
;
                                if ( ch != 'H' ) return syntax_error() ;
                        case seen_H:
-                               if ( n_left_to_process == 0 ) { scan_state = 
seen_H ; return Working ; }
+                               if ( n_left_to_process == 0 ) { scan_state = 
seen_H ; return source_state() ; }
                                ch = * next_character ++ ; -- n_left_to_process 
;
                                if ( ch != 'T' ) return syntax_error() ;
                        case seen_HT:
-                               if ( n_left_to_process == 0 ) { scan_state = 
seen_HT ; return Working ; }
+                               if ( n_left_to_process == 0 ) { scan_state = 
seen_HT ; return source_state() ; }
                                ch = * next_character ++ ; -- n_left_to_process 
;
                                if ( ch != 'T' ) return syntax_error() ;
                        case seen_HTT:
-                               if ( n_left_to_process == 0 ) { scan_state = 
seen_HTT ; return Working ; }
+                               if ( n_left_to_process == 0 ) { scan_state = 
seen_HTT ; return source_state() ; }
                                ch = * next_character ++ ; -- n_left_to_process 
;
                                if ( ch != 'P' ) return syntax_error() ;
                        case seen_HTTP:
-                               if ( n_left_to_process == 0 ) { scan_state = 
seen_HTTP ; return Working ; }
+                               if ( n_left_to_process == 0 ) { scan_state = 
seen_HTTP ; return source_state() ; }
                                ch = * next_character ++ ; -- n_left_to_process 
;
                                if ( ch != '/' ) return syntax_error() ;
                        case first_digits_0:
-                               if ( n_left_to_process == 0 ) { scan_state = 
first_digits_0 ; return Working ; }
+                               if ( n_left_to_process == 0 ) { scan_state = 
first_digits_0 ; return source_state() ; }
                                ch = * next_character ++ ; -- n_left_to_process 
;
                                if ( ! is_digit( ch ) ) return syntax_error() ;
                                the_result.major_number = ( ch - '0' ) ;
@@ -499,10 +499,10 @@
                                        }
                                }
                                scan_state = first_digits_0 ; 
-                               return Working ;
+                               return source_state() ;
                        label_second_digits_0:
                        case second_digits_0:
-                               if ( n_left_to_process == 0 ) { scan_state = 
second_digits_0 ; return Working ; }
+                               if ( n_left_to_process == 0 ) { scan_state = 
second_digits_0 ; return source_state() ; }
                                ch = * next_character ++ ; -- n_left_to_process 
;
                                if ( ! is_digit( ch ) ) return syntax_error() ;
                                the_result.minor_number = ( ch - '0' ) ;
@@ -520,7 +520,7 @@
                                        }
                                }
                                scan_state = first_digits_0 ; 
-                               return Working ;
+                               return source_state() ;
                }
        label_end_of_scan:
                ++ n_left_to_process ;
@@ -541,7 +541,7 @@
        {}
 
        //-------------------------
-       ACT::act_state
+       ACT::ACT_State
        Request_Scanner::
        scan( ACT::wakeup_listener * w )
        {
@@ -555,31 +555,33 @@
                switch ( current_state ) {
                        case in_method:
                                scan_method( w ) ;
-                               if ( scan_method.working() ) return 
ACT::Working ;
+                               if ( scan_method.working() ) { current_state = 
in_method ; return source_state() ; }
                                if ( scan_method.bad() ) goto label_error ;
-                               current_state = in_request_URI ;
                                // fall through
                        case in_request_URI:
                                scan_URI( w ) ;
-                               if ( scan_URI.working() ) return ACT::Working ;
+                               if ( scan_URI.working() ) { current_state = 
in_request_URI ; return source_state() ; }
                                if ( scan_URI.bad() ) goto label_error ;
-                               current_state = in_HTTP_version ;
+                               // fall through
+                       case post_request_URI:
+                               if ( n_left_to_process == 0 ) { current_state = 
post_request_URI ; return source_state() ; }
+                               -- n_left_to_process ;
+                               ch = * next_character ++ ;
+                               if ( ch != ' ' ) goto label_error ;
                                // fall through
                        case in_HTTP_version:
                                scan_version( w ) ;
-                               if ( scan_version.working() ) return 
ACT::Working ;
+                               if ( scan_version.working() ) { current_state = 
in_HTTP_version ; return source_state() ; }
                                if ( scan_version.bad() ) goto label_error ;
-                               current_state = p_final_CR ;
                                // fall through
                        case p_final_CR:
-                               if ( n_left_to_process == 0 ) return 
ACT::Working ;
+                               if ( n_left_to_process == 0 ) { current_state = 
p_final_CR ; return source_state() ; }
                                -- n_left_to_process ;
                                ch = * next_character ++ ;
                                if ( ch != '\r' ) goto label_error ;
-                               current_state = p_final_LF ;
                                // fall through
                        case p_final_LF:
-                               if ( n_left_to_process == 0 ) return 
ACT::Working ;
+                               if ( n_left_to_process == 0 ) { current_state = 
p_final_LF ; return source_state() ; }
                                -- n_left_to_process ;
                                ch = * next_character ++ ;
                                if ( ch != '\n' ) goto label_error ;

Index: HTTP/HTTP_Parse.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/HTTP/HTTP_Parse.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- HTTP/HTTP_Parse.hpp 1 Jul 2007 10:53:52 -0000       1.2
+++ HTTP/HTTP_Parse.hpp 10 Jul 2007 14:09:09 -0000      1.3
@@ -147,7 +147,7 @@
                IO::result_buffer<> r_field_name ;
 
                ///
-               ACT::act_state scan( ACT::wakeup_listener * ) ;
+               ACT::ACT_State scan( ACT::wakeup_listener * ) ;
 
        public:
                /// Ordinary constructor
@@ -196,7 +196,7 @@
                read_single_header read_single_header_action ;
 
                /// Body of action
-               ACT::act_state scan( ACT::wakeup_listener * ) ;
+               ACT::ACT_State scan( ACT::wakeup_listener * ) ;
 
        public:
                /// Ordinary constructor takes a nonblocking device as its 
source
@@ -250,7 +250,7 @@
                IO::result_buffer<> r_method ;
 
                ///
-               ACT::act_state scan( ACT::wakeup_listener * ) ;
+               ACT::ACT_State scan( ACT::wakeup_listener * ) ;
 
                ///
                void init() ;
@@ -288,7 +288,7 @@
                HTTP_Version the_result ;
 
                ///
-               ACT::act_state scan( ACT::wakeup_listener * ) ;
+               ACT::ACT_State scan( ACT::wakeup_listener * ) ;
 
                ///
                void init() ;
@@ -328,6 +328,7 @@
                enum request_parse_state {
                        in_method,
                        in_request_URI,
+                       post_request_URI,
                        in_HTTP_version,
                        p_final_CR,
                        p_final_LF,
@@ -347,7 +348,7 @@
                Request_Version_Scanner scan_version ;
 
                ///
-               ACT::act_state scan( ACT::wakeup_listener * ) ;
+               ACT::ACT_State scan( ACT::wakeup_listener * ) ;
 
        public:
                /// Ordinary constructor takes a nonblocking device as its 
source

Index: HTTP/URI.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/HTTP/URI.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- HTTP/URI.cpp        1 Jul 2007 10:53:52 -0000       1.2
+++ HTTP/URI.cpp        10 Jul 2007 14:09:09 -0000      1.3
@@ -99,7 +99,7 @@
        //--------------------------------------------------
        // URI_Scanner
        //--------------------------------------------------
-       ACT::act_state
+       ACT::ACT_State
        URI_Scanner::
        scan( ACT::wakeup_listener * ) {
                // If we are at EOF, some states may accept, some may reject.
@@ -165,7 +165,7 @@
                                        }
                                }
                                current_state = scheme_0 ;
-                               return ACT::Working ;
+                               return source_state() ;
                        label_scheme:
                        case scheme:
                                while ( n_left_to_process > 0 ) {
@@ -184,7 +184,7 @@
                                        }
                                }
                                current_state = scheme ;
-                               return ACT::Working ;
+                               return source_state() ;
                        //-------------------------
                        // hier-part
                        //-------------------------
@@ -208,7 +208,7 @@
                                        }
                                }
                                current_state = hier_part_0 ;
-                               return ACT::Working ;
+                               return source_state() ;
                        //----------
                        label_hier_part_slash:
                        case hier_part_slash:
@@ -237,7 +237,7 @@
                                        }
                                }
                                current_state = hier_part_slash ;
-                               return ACT::Working ;
+                               return source_state() ;
                        //-------------------------
                        // authority
                        //-------------------------
@@ -261,7 +261,7 @@
                                        }
                                }
                                current_state = authority_0 ;
-                               return ACT::Working ;
+                               return source_state() ;
                        //----------
                        label_auth_unknown:
                        case auth_unknown:
@@ -285,7 +285,7 @@
                                        }
                                }
                                current_state = auth_unknown ;
-                               return ACT::Working ;
+                               return source_state() ;
                        //-------------------------
                        // path
                        //-------------------------
@@ -315,7 +315,7 @@
                                        }
                                }
                                current_state = path_absolute_0 ;
-                               return ACT::Working ;
+                               return source_state() ;
                        //----------
                        label_path_absolute:
                        case path_absolute:
@@ -340,7 +340,7 @@
                                        }
                                }
                                current_state = path_absolute ;
-                               return ACT::Working ;
+                               return source_state() ;
                        //----------
                        label_path_abempty_0:
                        case path_abempty_0:
@@ -368,7 +368,7 @@
                                        }
                                }
                                current_state = path_absolute_0 ;
-                               return ACT::Working ;
+                               return source_state() ;
                        //-------------------------
                        // query
                        //-------------------------
@@ -390,7 +390,7 @@
                                        }
                                }
                                current_state = query_0 ;
-                               return ACT::Working ;
+                               return source_state() ;
                        //----------
                        label_query:
                        case query:
@@ -410,7 +410,7 @@
                                        }
                                }
                                current_state = query_0 ;
-                               return ACT::Working ;
+                               return source_state() ;
                        //-------------------------
                        // fragment
                        //-------------------------
@@ -430,7 +430,7 @@
                                        }
                                }
                                current_state = fragment_0 ;
-                               return ACT::Working ;
+                               return source_state() ;
                        //----------
                        label_fragment:
                        case fragment:
@@ -447,7 +447,7 @@
                                        }
                                }
                                current_state = fragment ;
-                               return ACT::Working ;
+                               return source_state() ;
                        //----------
                        label_done_unget_last_character:
                                uri.r_URI.set_length( next_character - 
URI_begin - 1 ) ;

Index: HTTP/URI.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/HTTP/URI.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- HTTP/URI.hpp        1 Jul 2007 10:53:52 -0000       1.2
+++ HTTP/URI.hpp        10 Jul 2007 14:09:10 -0000      1.3
@@ -70,6 +70,11 @@
        } ;
 
        //-------------------------
+       /** \class URI_Scanner
+        *
+        *      \todo Fix the silent consumption of the next character after 
the URI.
+        *              It interferes with a caller's grammar.
+        */
        class URI_Scanner
                : public IO::Stream_Consumer
        {
@@ -80,7 +85,7 @@
                char * component_begin ;
 
                ///
-               ACT::act_state scan( ACT::wakeup_listener * ) ;
+               ACT::ACT_State scan( ACT::wakeup_listener * ) ;
 
                ///
                void init() ;

Index: HTTP/unit_tests/Test_HTTP.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/HTTP/unit_tests/Test_HTTP.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- HTTP/unit_tests/Test_HTTP.cpp       1 Jul 2007 10:53:53 -0000       1.2
+++ HTTP/unit_tests/Test_HTTP.cpp       10 Jul 2007 14:09:10 -0000      1.3
@@ -454,7 +454,13 @@
 }
 
 //---------------------------------------------------------------------------
-BOOST_AUTO_TEST_CASE( Invalid_Version_Request )
+/* Scanning regular URI and "*"-URI are handled differently internally.
+ * This pair of tests once had different outcomes; the first failed and second 
passed.
+ * URI scanning was consuming an extra character for ordinary URI but not "*".
+ * HTTP-Request scanning wasn't looking for the space after its URI.
+ * In the test that passed, one defect was masking the other.
+ */
+BOOST_AUTO_TEST_CASE( Invalid_Version_Request_1 )
 {
        char request[] = "GET * HTTP/1.0\r\n" ;
        IO::String_Device device( request ) ;
@@ -464,6 +470,20 @@
 
        cygnal::HTTP::HTTP_Behavior behavior( & device ) ;
        behavior() ;
-       BOOST_CHECK( behavior.completed() ) ;
+       BOOST_REQUIRE( behavior.completed() ) ;
+       BOOST_CHECK( device.string_written() == string( response ) ) ;
+}
+
+BOOST_AUTO_TEST_CASE( Invalid_Version_Request_2 )
+{
+       char request[] = "GET http://foo.com/ HTTP/1.0\r\n" ;
+       IO::String_Device device( request ) ;
+       char response[] = 
+               "HTTP/1.1 505 HTTP Version Not Supported" "\r\n"
+               "Connection: close" "\r\n" ;
+
+       cygnal::HTTP::HTTP_Behavior behavior( & device ) ;
+       behavior() ;
+       BOOST_REQUIRE( behavior.completed() ) ;
        BOOST_CHECK( device.string_written() == string( response ) ) ;
 }
\ No newline at end of file

Index: IO/IO_Device.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/IO_Device.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/IO_Device.hpp    1 Jul 2007 10:53:53 -0000       1.2
+++ IO/IO_Device.hpp    10 Jul 2007 14:09:10 -0000      1.3
@@ -125,8 +125,8 @@
                : public Source 
        {
        protected:
-               virtual ACT::act_state source_run( ACT::wakeup_listener * ) =0 ;
-               inline ACT::act_state run( ACT::wakeup_listener * w ) { return 
source_run( w ) ; }
+               virtual ACT::ACT_State source_run( ACT::wakeup_listener * ) =0 ;
+               inline ACT::ACT_State run( ACT::wakeup_listener * w ) { return 
source_run( w ) ; }
        } ;
 
        //-------------------------
@@ -140,7 +140,7 @@
                : public SSource
        {
                S & the_source ;
-               inline ACT::act_state source_run( ACT::wakeup_listener * w ) { 
return the_source.run( w ) ; }
+               inline ACT::ACT_State source_run( ACT::wakeup_listener * w ) { 
return the_source.run( w ) ; }
        public:
                Source_Adapter( S & source )
                        : the_source( source )
@@ -157,8 +157,8 @@
        //-------------------------
        class SSink : public Sink {
        protected:
-               virtual ACT::act_state sink_run( ACT::wakeup_listener * ) =0 ;
-               inline ACT::act_state run( ACT::wakeup_listener * w ) { return 
sink_run( w ) ; }
+               virtual ACT::ACT_State sink_run( ACT::wakeup_listener * ) =0 ;
+               inline ACT::ACT_State run( ACT::wakeup_listener * w ) { return 
sink_run( w ) ; }
        } ;
 
        //-------------------------
@@ -172,7 +172,7 @@
                : public SSink
        {
                S & the_sink ;
-               inline ACT::act_state sink_run( ACT::wakeup_listener * w ) { 
return the_sink.run( w ) ; }
+               inline ACT::ACT_State sink_run( ACT::wakeup_listener * w ) { 
return the_sink.run( w ) ; }
        public:
                Sink_Adapter( S & sink )
                        : the_sink( sink )
@@ -206,8 +206,8 @@
        {
                In the_source ;
                Out the_sink ;
-               inline ACT::act_state sink_run( ACT::wakeup_listener * w ) { 
return the_sink.run( w ) ; }
-               inline ACT::act_state source_run( ACT::wakeup_listener * w ) { 
return the_source.run( w ) ; }
+               inline ACT::ACT_State sink_run( ACT::wakeup_listener * w ) { 
return the_sink.run( w ) ; }
+               inline ACT::ACT_State source_run( ACT::wakeup_listener * w ) { 
return the_source.run( w ) ; }
        public:
                Split_Device( In in, Out out )
                        : the_source( in ), the_sink( out )
@@ -230,7 +230,7 @@
                Oldsource & the_source ;
                Action the_action ;
 
-               inline ACT::act_state run( ACT::wakeup_listener * w ) { return 
the_action.operator()( w ) ; }
+               inline ACT::ACT_State run( ACT::wakeup_listener * w ) { return 
the_action.operator()( w ) ; }
 
                template< class In, class Out > friend class Split_Device ;
        public:

Index: IO/IO_Generator.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/IO_Generator.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/IO_Generator.cpp 1 Jul 2007 10:53:53 -0000       1.2
+++ IO/IO_Generator.cpp 10 Jul 2007 14:09:10 -0000      1.3
@@ -15,7 +15,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/// \file IO_Service.cpp
+/// \file IO_Generator.cpp
 
 #include "IO_Generator.hpp"
 
@@ -28,13 +28,13 @@
        {}
 
        //-------------------------
-       ACT::act_state
+       ACT::ACT_State
        Device_Adapter::
        run( ACT::wakeup_listener * w )
        {
                the_generator( w ) ;
                if ( the_generator.bad() ) return set_bad() ;
-               if ( the_generator.working() ) return ACT::Working ;
+               if ( the_generator.working() ) return set_ready() ;
                // Assert the_generator has a result ready for us.
                
                the_result = the_behavior_factory( the_generator.result() ) ;

Index: IO/IO_Generator.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/IO_Generator.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/IO_Generator.hpp 1 Jul 2007 10:53:53 -0000       1.2
+++ IO/IO_Generator.hpp 10 Jul 2007 14:09:10 -0000      1.3
@@ -74,7 +74,7 @@
        /**     \class Device_Adapter
         */
        class Device_Adapter
-               : public ACT::Generator
+               : public ACT::Obsolete_Generator                // will rewrite 
as deriving from ACT::Generator
        {
                /// We use shared_ptr here
                Device_Generator & the_generator ;
@@ -89,7 +89,7 @@
                Device_Adapter( Device_Generator & x, Behavior_Factory & y ) ;
 
                ///
-               ACT::act_state run( ACT::wakeup_listener * w ) ;
+               ACT::ACT_State run( ACT::wakeup_listener * w ) ;
 
                ///
                ACT::act result() ;

Index: IO/Stream_Consumer.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/Stream_Consumer.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/Stream_Consumer.cpp      1 Jul 2007 10:53:53 -0000       1.2
+++ IO/Stream_Consumer.cpp      10 Jul 2007 14:09:10 -0000      1.3
@@ -15,7 +15,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/**    \file Stream_Consumer.hpp
+/**    \file Stream_Consumer.cpp
  *     \brief Assistance for treating ACT block readers as a stream.
  *
  *     Implementing a stream model with ACT-based I/O requires resolving a 
number of competing concerns.
@@ -60,7 +60,7 @@
        {}
 
        //-------------------------
-       ACT::act_state
+       ACT::ACT_State
        Stream_Consumer::
        run( ACT::wakeup_listener * w )
        {
@@ -79,7 +79,7 @@
                                if ( source_still_working() ) {
                                        // Assert our underlying source is 
still working.
                                        // Nothing left to do now.
-                                       return ACT::Working ; 
+                                       return the_source -> internal_state() ; 
                                }
                                if ( source_went_bad() ) {
                                        // Assert our underlying source went 
bad.
@@ -105,7 +105,7 @@
                                if ( source_still_working() ) {
                                        // Assert our underlying source is 
still working.
                                        // Nothing left to do now.
-                                       return ACT::Working ; 
+                                       return the_source -> internal_state() ; 
                                }
                                if ( source_went_bad() ) {
                                        // Assert our underlying source went 
bad.
@@ -123,10 +123,9 @@
                                        caller_next_character = next_character ;
                                        caller_n_left_to_process = 
n_left_to_process ;
                                }
-                               return ACT::Completed ;
-                       } else if ( bad() ) {
-                               return ACT::Completed ;
                        }
+                       if ( ! working() ) return internal_state() ;
+                       // Assert scanning remains incomplete
                }
        }
 

Index: IO/Stream_Consumer.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/Stream_Consumer.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/Stream_Consumer.hpp      1 Jul 2007 10:53:53 -0000       1.2
+++ IO/Stream_Consumer.hpp      10 Jul 2007 14:09:10 -0000      1.3
@@ -63,7 +63,7 @@
                unsigned int number_of_lookahead_characters_required ;
 
                /// Polymorphic scanner.
-               virtual ACT::act_state scan( ACT::wakeup_listener * ) =0 ;
+               virtual ACT::ACT_State scan( ACT::wakeup_listener * ) =0 ;
 
                /// Initial action
                virtual void init() {} ;
@@ -98,6 +98,9 @@
                /// [replenish result]
                inline bool source_went_bad() { return the_source -> bad() ; }
 
+               /// [replenish result]
+               inline ACT::ACT_State source_state() { return the_source -> 
internal_state() ; }
+
                ///
                inline void require_lookahead( unsigned int n ) { 
number_of_lookahead_characters_required = n ; }
 
@@ -113,12 +116,12 @@
                bool first_time ;
 
                /// [error] Indicate a syntax error at the current location.
-               ACT::act_state syntax_error() { return set_bad() ; }
+               ACT::ACT_State syntax_error() { return set_bad() ; }
 
        public:
                /// The class implements the ACT invocation.
                /// This function wraps our own polymorphic \c run.
-               ACT::act_state run( ACT::wakeup_listener * ) ;
+               ACT::ACT_State run( ACT::wakeup_listener * ) ;
 
        } ;
 

Index: IO/test_support/Null_Device.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/test_support/Null_Device.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/test_support/Null_Device.cpp     1 Jul 2007 10:53:54 -0000       1.2
+++ IO/test_support/Null_Device.cpp     10 Jul 2007 14:09:10 -0000      1.3
@@ -15,7 +15,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/**    \file Null_Device.hpp
+/**    \file Null_Device.cpp
  *     \brief 
  */
 
@@ -31,7 +31,7 @@
                set_completed() ;
        }
 
-       ACT::act_state
+       ACT::ACT_State
        Null_Source::
        run( ACT::wakeup_listener * )
        {

Index: IO/test_support/Null_Device.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/test_support/Null_Device.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/test_support/Null_Device.hpp     1 Jul 2007 10:53:54 -0000       1.2
+++ IO/test_support/Null_Device.hpp     10 Jul 2007 14:09:10 -0000      1.3
@@ -34,7 +34,7 @@
                friend class Null_Device ;
                template< class S > friend class Source_Adapter ;
 
-               ACT::act_state run( ACT::wakeup_listener * ) ;
+               ACT::ACT_State run( ACT::wakeup_listener * ) ;
 
        public:
                /// Only need a default constructor for a source that's always 
the same.
@@ -57,7 +57,7 @@
                template< class In, class Out > friend class Split_Device ;
 
                /// The write action.
-               ACT::act_state run( ACT::wakeup_listener * ) { return 
set_completed() ; }
+               ACT::ACT_State run( ACT::wakeup_listener * ) { return 
set_completed() ; }
 
                /// [out parameter value]
                size_t out_n_written ;
@@ -80,8 +80,8 @@
                Null_Sink the_sink ;
                Null_Source the_source ;
                
-               inline ACT::act_state source_run( ACT::wakeup_listener * w ) { 
return Device::SSource::set_state( the_source.run( w ) ) ; }
-               inline ACT::act_state sink_run( ACT::wakeup_listener * w ) { 
return Device::SSink::set_state( the_sink.run( w ) ) ; }
+               inline ACT::ACT_State source_run( ACT::wakeup_listener * w ) { 
return Device::SSource::set_state( the_source.run( w ) ) ; }
+               inline ACT::ACT_State sink_run( ACT::wakeup_listener * w ) { 
return Device::SSink::set_state( the_sink.run( w ) ) ; }
 
        public:
                ///

Index: IO/test_support/Null_Filter.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/test_support/Null_Filter.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/test_support/Null_Filter.cpp     1 Jul 2007 10:53:54 -0000       1.2
+++ IO/test_support/Null_Filter.cpp     10 Jul 2007 14:09:10 -0000      1.3
@@ -44,7 +44,7 @@
        }
 
        //---------------
-       ACT::act_state
+       ACT::ACT_State
        null_read_filter::
        run( ACT::wakeup_listener * w )
        {

Index: IO/test_support/Null_Filter.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/test_support/Null_Filter.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/test_support/Null_Filter.hpp     1 Jul 2007 10:53:54 -0000       1.2
+++ IO/test_support/Null_Filter.hpp     10 Jul 2007 14:09:10 -0000      1.3
@@ -38,7 +38,7 @@
                Source * the_source ;
 
                /// 
-               ACT::act_state run( ACT::wakeup_listener * ) ;
+               ACT::ACT_State run( ACT::wakeup_listener * ) ;
 
        public:
                /// Ordinary constructor

Index: IO/test_support/String_Device.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/test_support/String_Device.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/test_support/String_Device.cpp   1 Jul 2007 10:53:54 -0000       1.2
+++ IO/test_support/String_Device.cpp   10 Jul 2007 14:09:10 -0000      1.3
@@ -15,7 +15,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/// \file String_Device.hpp
+/// \file String_Device.cpp
 
 #include "String_Device.hpp"
 #include <string>
@@ -81,7 +81,7 @@
        }
 
        //-------------------------
-       ACT::act_state
+       ACT::ACT_State
        String_Device::
        source_run( ACT::wakeup_listener * )
        {
@@ -110,7 +110,7 @@
        String_Device::
        reset()
        {
-               SSource::set_working() ;
+               SSource::set_ready() ;
        }
 
        //-------------------------
@@ -137,7 +137,7 @@
        }
 
        //-------------------------
-       ACT::act_state
+       ACT::ACT_State
        String_Device::
        sink_run( ACT::wakeup_listener * )
        {

Index: IO/test_support/String_Device.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/test_support/String_Device.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/test_support/String_Device.hpp   1 Jul 2007 10:53:54 -0000       1.2
+++ IO/test_support/String_Device.hpp   10 Jul 2007 14:09:10 -0000      1.3
@@ -49,7 +49,7 @@
                contiguous_buffer<> the_next_segment ;
 
                /// [source] read activation body
-               ACT::act_state source_run( ACT::wakeup_listener * ) ;
+               ACT::ACT_State source_run( ACT::wakeup_listener * ) ;
 
                /// [sink] This string receives the results of write operations.
                std::string the_sink_string ;
@@ -61,7 +61,7 @@
                buffer next_to_write ;
 
                /// [sink] activation body
-               ACT::act_state sink_run( ACT::wakeup_listener * ) ;
+               ACT::ACT_State sink_run( ACT::wakeup_listener * ) ;
 
        public:
                /// Ordinary constructor

Index: IO/test_support/String_Generator.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/test_support/String_Generator.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/test_support/String_Generator.cpp        1 Jul 2007 10:53:54 -0000       
1.2
+++ IO/test_support/String_Generator.cpp        10 Jul 2007 14:09:10 -0000      
1.3
@@ -36,11 +36,11 @@
        }
 
        ///
-       ACT::act_state 
+       ACT::ACT_State 
        String_Generator::
        run( ACT::wakeup_listener * )
        {
-               if ( the_queue.empty() ) return ACT::Working ;
+               if ( the_queue.empty() ) return ACT::ACT_State( 
ACT::ACT_State::Ready ) ;
                the_result = shared_ptr< IO::Device >( new String_Device( 
the_queue.front() ) ) ;
                the_queue.pop() ;
                return set_completed() ;
@@ -65,7 +65,7 @@
        reset()
        {
                if ( bad() ) return ;
-               set_working() ;
+               set_ready() ;
        }
 
 } // end namespace IO

Index: IO/test_support/String_Generator.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/test_support/String_Generator.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/test_support/String_Generator.hpp        1 Jul 2007 10:53:54 -0000       
1.2
+++ IO/test_support/String_Generator.hpp        10 Jul 2007 14:09:10 -0000      
1.3
@@ -50,7 +50,7 @@
                void add_source( std::string x ) ;
 
                ///
-               ACT::act_state run( ACT::wakeup_listener * ) ;
+               ACT::ACT_State run( ACT::wakeup_listener * ) ;
 
                /// result accessor
                shared_ptr< IO::Device > result() ;

Index: IO/unit_tests/Test_Service.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/IO/unit_tests/Test_Service.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- IO/unit_tests/Test_Service.cpp      1 Jul 2007 10:53:55 -0000       1.2
+++ IO/unit_tests/Test_Service.cpp      10 Jul 2007 14:09:11 -0000      1.3
@@ -27,7 +27,7 @@
 {
 public:
        Null_Behavior() { set_completed() ; }
-       ACT::act_state run( ACT::wakeup_listener * ) { return ACT::Completed ; }
+       ACT::ACT_State run( ACT::wakeup_listener * ) { return set_completed() ; 
}
 } ;
 
 //-------------------------

Index: Net/Net.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/Net/Net.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- Net/Net.hpp 1 Jul 2007 10:53:55 -0000       1.2
+++ Net/Net.hpp 10 Jul 2007 14:09:11 -0000      1.3
@@ -189,7 +189,7 @@
         *              in order to support the RAII convention.
         *      The resource is the socket handle itself.
         *
-        *      \inv Instance holds an allocated socket.
+        *      \invariant Instance holds an allocated socket.
         *
         *      \par Limitations
         *      - Class opens sockets in default streaming protocol (meaning 
TCP) only.

Index: Net/Old_Device.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/Net/Old_Device.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- Net/Old_Device.hpp  1 Jul 2007 10:53:55 -0000       1.2
+++ Net/Old_Device.hpp  10 Jul 2007 14:09:11 -0000      1.3
@@ -15,7 +15,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/**    \file IO_Device.hpp
+/**    \file Old_Device.hpp
  *     \brief Basic abstractions for handling ACT-based I/O
  *
  *     \par Design Notes

Index: Net/socket_device.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/Net/socket_device.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- Net/socket_device.cpp       1 Jul 2007 10:53:55 -0000       1.2
+++ Net/socket_device.cpp       10 Jul 2007 14:09:11 -0000      1.3
@@ -188,7 +188,7 @@
        {}
 
        //-------------------------
-       ACT::act_state 
+       ACT::ACT_State 
        read_action::
        run( ACT::wakeup_listener * waken )
        {
@@ -218,9 +218,9 @@
                        } else if ( error == EINTR ) {
                                // Assert the read() call was interrupted.
                                // Rather than enter a loop here, we let the 
scheduler retry.
-                               if ( waken != 0 ) {
-                                       ( * waken )() ;
-                               }
+
+                               /// \todo Implement a recovery tactic.
+                               set_bad() ;
                        } else {
                                // Assert the socket had a non-recoverable error
                                set_bad() ;
@@ -253,7 +253,7 @@
        } ;
 
        //-------------------------
-       ACT::act_state 
+       ACT::ACT_State 
        write_action::
        run( ACT::wakeup_listener * waken )
        {
@@ -289,9 +289,9 @@
                        } else if ( errno == EINTR ) {
                                // Assert the read() call was interrupted.
                                // Rather than enter a loop here, we let the 
scheduler retry.
-                               if ( waken != 0 ) {
-                                       ( * waken )() ;
-                               }
+
+                               /// \todo Implement a recovery tactic.
+                               set_bad() ;
                        } else {
                                // Assert the socket had a non-recoverable error
                                set_bad() ;

Index: Net/socket_device.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/Net/socket_device.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- Net/socket_device.hpp       1 Jul 2007 10:53:55 -0000       1.2
+++ Net/socket_device.hpp       10 Jul 2007 14:09:11 -0000      1.3
@@ -231,7 +231,7 @@
                //---------------
                /**
                 */
-               ACT::act_state run( ACT::wakeup_listener * waken ) ;
+               ACT::ACT_State run( ACT::wakeup_listener * waken ) ;
 
                //---------------
                /** \brief Ordinary constructor 
@@ -262,7 +262,7 @@
 
        public:
                /// Action operator actually does the write.
-               ACT::act_state run( ACT::wakeup_listener * waken ) ;
+               ACT::ACT_State run( ACT::wakeup_listener * waken ) ;
 
                /// Ordinary constructor
                write_action(

Index: Net/unit_tests/Test_socket_device.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/Net/unit_tests/Test_socket_device.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- Net/unit_tests/Test_socket_device.cpp       1 Jul 2007 10:53:55 -0000       
1.2
+++ Net/unit_tests/Test_socket_device.cpp       10 Jul 2007 14:09:11 -0000      
1.3
@@ -15,7 +15,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/// \file Test_Service.cpp
+/// \file Test_socket_device.cpp
 
 #include "config.h"
 

Index: unit_tests/Permutation.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/unit_tests/Permutation.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- unit_tests/Permutation.hpp  1 Jul 2007 10:53:56 -0000       1.2
+++ unit_tests/Permutation.hpp  10 Jul 2007 14:09:11 -0000      1.3
@@ -107,6 +107,8 @@
                throw std::exception( "Can only compare against end-iterators 
in the present implementation." ) ;
        }
 
+       /**     \class test_function
+        */
        boost::function< void( void ) > test_function() const
        {
                return boost::bind( f, the_vector.begin(), the_vector.end() ) ;

Index: unit_tests/Random_Permutation.cpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/unit_tests/Random_Permutation.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- unit_tests/Random_Permutation.cpp   1 Jul 2007 10:53:56 -0000       1.2
+++ unit_tests/Random_Permutation.cpp   10 Jul 2007 14:09:11 -0000      1.3
@@ -18,7 +18,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/// \file Random_Permutation.hpp
+/// \file Random_Permutation.cpp
 /// \brief A permutation generator for test cases.
 
 #include "Random_Permutation.hpp"

Index: unit_tests/Test_Support.hpp
===================================================================
RCS file: /sources/gnash/gnash/cygnal/unit_tests/Test_Support.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- unit_tests/Test_Support.hpp 1 Jul 2007 10:53:56 -0000       1.2
+++ unit_tests/Test_Support.hpp 10 Jul 2007 14:09:11 -0000      1.3
@@ -133,7 +133,7 @@
 } ;
 
 //--------------------------------------------------
-/**    \fn make_generator
+/**    \fn make_generator template< class Gen > auto_generator make_generator( 
Gen generator_instance, std::string name )
  *     \brief Adapter function allowing use of type inference to initialize 
test generator.
  */
 template< class Gen >

Index: ACT/ACT.doxygen.txt
===================================================================
RCS file: ACT/ACT.doxygen.txt
diff -N ACT/ACT.doxygen.txt
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ACT/ACT.doxygen.txt 10 Jul 2007 14:09:08 -0000      1.1
@@ -0,0 +1,174 @@
+/**
+
+\page ACT Module ACT: Asynchronous Computation Task
+
+       An ACT is the moral equivalent of a thread in an asynchronous, 
cooperative, non-preemptive, multitasking environment.
+       The name "ACT" is itself an acronym for Asynchronous Computation Task.
+
+\section s_Speed Speed is the Reason
+
+       The whole point of the ACT environment is high performance.
+       In comes at a cost, certainly; the tradeoffs are not trivial.
+       Preemptive multitasking is easier to implement, but at the cost of the 
overhead of context switches.
+       Each context switch must preserve the entire state of computation, both 
internal CPU state as well as memory.
+       The operating system (or other control facility) is ignorant, perforce, 
of the details of a computational unit, be it process or thread.
+       Thus it cannot optimize a context switch in any way, 
+               either by picking a fortuitous point to interrupt (avoiding 
saving CPU state)
+               or by saving less state on the stack than everything (incurring 
cache and swapping penalties).
+       There are two primary benefits of the ACT model.
+       The first primary benefit, then, is the elimination of context switch 
overhead.
+
+       The second benefit is its natural fit with asynchronous and 
non-blocking I/O.
+       Technically, avoiding context switches mandates working within a single 
thread and using cooperative scheduling.
+       Cooperative scheduling means that a task must manually yield its 
control of the CPU back to its environment.
+       The natural time to do that is when receiving a "would block" return on 
a non-blocking I/O call.
+       Every program that uses non-blocking I/O needs to be able to resume 
itself at the effective point where the computation left off.
+       In the ACT system, this is simply a requirement for all tasks, so doing 
it for non-blocking I/O adds no extra overhead.
+       The implementation pattern that comes to the fore is the "state of a 
partial computation".
+       One element of a partial computation state is a record of what I/O 
operation has been set to operate asynchronously.
+
+\section s_Elements An Oveview of the Elements of the ACT Environment
+       The main elements of the ACT environment the following:
+       - \b Actions.  
+               These are ACT classes that do all the work; it's the equivalent 
of a thread body.
+               The ultimate purpose of the ACT environment is to provide an 
execution context for actions.
+               An action runs until it yields (typically because it would 
block).
+               At such a time it enters a waiting state, waiting to be 
awakened as a result of further activity.
+       - \b Scheduler.
+               In preemptive multitasking environments, the scheduling 
function is provided transparently.
+               In the ACT environment, ordinary actions see scheduling as 
transparent,
+                       but the scheduler is visible to certain primitives, 
particularly those involved with I/O.
+               A scheduler is single-threaded and is designed to be the body 
of a thread.
+               The scheduler, however, is not a singleton, as the preferred 
deployment configuration is one-scheduler-per-CPU.
+       - \b Demons.
+               Demons are a category of actions that run persistently in the 
scheduler.
+               The scheduler views ordinary actions as tasks, which are 
expected to eventually terminate.
+               The scheduler has different execution policies for demons and 
tasks.
+               The two most significant kinds of demons are services and 
monitors.
+       - \b Services.
+               A service is a demon that generates new tasks.
+               A service typically represents some kind of bound input device, 
activity at which needs some response.
+               The response to such input activity is a new task.
+               For example, a socket listening at port 80 generates a new HTTP 
protocol task for each incoming connection. 
+               As a rule, services represent input response, but not as a 
requirement.
+               A service may generate new tasks based on purely internal 
considerations as well.
+       - \b Monitors.
+               A monitor is a demon that wakes up tasks from their waiting 
state.
+               A task, once it yields to wait for new activity, won't be 
scheduled until something else rouses it.
+               For each waiting task, there is some monitor demon that has 
responsibility for waking it up.
+               Sensing the activity that triggers a wake-up is domain-specific,
+                       so there's a separate monitor class for each kind of 
waiting, in particular each kind of I/O.
+       - <b>Listener Actions</b>.
+               The code for actions is recursive, one action calling another 
as needed.
+               This is as for ordinary code, with the distinction that the 
action invariants must be preserved at each call.
+               A listener action is a primitive action that calls no other 
action and cooperates with a monitor for wake-up.
+               As a result, each leaf in the call graph of an action is either 
a listener action or one that spontaneously yields.
+
+\section s_Quiescence Quiescence
+
+       What does the scheduler do when it has no task work that needs to be 
done?
+       If it also has no demons running, it simply exits.
+       If it does have demons running, it activates them round-robin until 
they all terminate or generate new tasks.
+       In the first approximation, then, the scheduler will consume all 
available CPU unless somehow throttled.
+       The basic tactic to throttle a quiescent scheduler is to have a demon 
running that blocks.
+       This is the only place in the system where blocking is an ordinary part 
of the architecture.
+
+       Now just to be contradictory, consider the following example.
+       The scheduler is running in a dedicated device where power consumption 
due to CPU usage isn't an issue.
+       Using 100% CPU is no problem here.
+       So a blocking demon for quiescent operation isn't necessary in this 
case.
+       The example shows that blocking is used during quiescent operation to 
be kind to some larger execution environment.
+
+       So suppose that the scheduler is running some demon that can block.
+       How that demon unblocks is the real issue.
+       The easiest way to unblock generates a polling algorithm: it simply 
waits some amount of time, then unblocks.
+       An implementation of this idea is the class ACT::Pause_Demon.
+       Without the motivation to properly handle quiescent operation, it's a 
bit of a mystery why there should be a task that just eats time.
+
+       \b Note: Interrupt I/O is not yet implemented.
+       It's on the timeline.
+
+       The other way of unblocking is by interrupt.
+       With this method, actions waiting for asynchronous I/O receive 
notifications on another thread.
+       This notification triggers unblocking in the demon that's blocked in 
the same same thread as the waiting action.
+       It's desirable that all interruptions from any source converge upon a 
single demon that aggregates them.
+       The alternatives require a hybrid algorithm with polling that doesn't 
perform well.
+
+       These two strategies each have advantageous niches.
+       The downside to a polling strategy is that under quiescence it consumes 
some constant fraction of CPU
+               and has a certain average latency in its responses, 
proportional to that responsiveness.
+       Its upside is that under load it does no work over and above what it 
would have do anyway.
+       The downside of an interrupt stategy is that there's task-switching 
overhead in the interrupt process.
+       Its upside is that under quiescence it has zero CPU overhead and good 
latency response.
+       The hybrid strategy is to switch between these two depending on load.
+
+       From a development sequence point of view, however, polling is easy and 
interrupt is hard.
+       Thus, polling was done at the outset.
+       As of this writing, interrupting is not implemented.
+       Since the first use case of the scheduler is for deployment on 
dedicated server hardware, 
+               this absence has not become problematic.
+       Once the ACT environment is used on client software, however, this will 
have to change.
+
+       The ACT architecture enables the separation of polling-vs.-interrupt 
strategy by using listener actions and monitors.
+       While the underlying I/O calls may be identical, there are different 
control structures around them for the two strategies.
+       Once both are implemented, however, swapping between them is a matter 
of link-time configuration.
+       Implementing a hybrid strategy requires writing more effort, but it too 
is simply linked in.
+       As a result, there's little project risk to delaying the interrupt and 
hybrid strategies.
+
+\section s_Shutdown Shutdown
+
+       \b Note: The facilities in this section are not yet implemented for the 
most part.
+
+       Shutting down a server is an important use case for system 
administrators.
+       They have different reasons for shutting down a process, ranging from 
emergency ("Process is a security breach!") to the languid ("Regular version 
upgrade.").
+       The ACT environment takes the basic stance that shutdown is 
application-specific.
+       The application defines a class representing a shutdown order,
+               and it's a parameter to both the scheduler and to actions.
+       The author of an action class is responsible for shutting them down in 
whatever way they may find appropriate
+               and documenting that behavior.
+       There remains the issue of what the scheduler does.
+
+       To start with, there's always the option of killing it pre-emptively.
+       It's not graceful, but it's available.
+       So let's assume that the application wishes to cooperate with the 
scheduler.
+
+       A scheduler must determine what to do with the actions in its 
scheduling queue when it receives a shutdown order.
+       The simplest, though rarely the best, thing to do is nothing.
+       It is able to simply cease processing altogether and return from its 
main loop with all its items left intact.
+       Up to this stage, this is an order to suspend.
+       Now, if the thread main function were a scheduler's execution loop (as 
it supports),
+               to continue to do nothing means that the thread terminates and 
presumably then the scheduler goes out of scope.
+
+       There's also a slightly more aggressive version of nothing, 
+               which is to remove all references to a scheduled item from the 
scheduling queue.
+       In the typical case, the only reference to an item is within the queue 
(think tasks generated by a service)
+               and so this causes such an object to go out of scope 
immediately.
+       Removing such a reference is the regular policy if an action completes 
itself normally.
+       This removal is unusual because it happens when an action is still in 
an incomplete state.      
+
+       If shutdown is not required immediately, then the scheduler may 
continue to execute actions
+               in anticipating of termination, presumably in the near future.
+       The next question is how many times to perform such execution.
+       As the proverbial angel-on-pinheads, the choice is between a definite 
and an indefinite bound.
+       If a definite execution bound is desired, it might be by execution 
count or by a time limit (or both).
+
+       summarizing, we have the following shutdown algorithm, with its main 
points of configuration:
+       - Decide upon a cooperative shutdown.
+       - Construct a shutdown parameter and invoke the scheduler's shutdown 
function with it.
+       - If the scheduler is immediately suspending, do so now, deleting 
references if requested.
+       - Call the shutdown interface on each action in the scheduling queue.
+       - If the scheduler has a zero execution bound (either by count or in 
time), return now, deleting references if requested.
+       - If execution bounds are not in place, resume ordinary operations.  
The actions will shut themselves down.
+       - If execution bound are in place, continue with bounded operation.  
When an action overreaches a bound, delete it if requested.
+
+\section s_Implementation_Tactics Implementation Tactics
+
+       - <b>Scheduler-specific Storage</b>.
+               It is permitted to have one monitor scheduled for each waiting 
task.
+               In an I/O-bound environment, most tasks at any given time are 
waiting for I/O,
+                       so a one-monitor-per-waiting-task policy almost doubles 
the size of the scheduling queue.
+               To alleviate this issue, scheduler-specific storage enables a 
single monitor for all waiting tasks of the same category.
+               This works by allowing a listener action to navigate to the 
correct monitor for its scheduler.
+               Using one monitor per scheduler rather than one monitor per 
system eliminates
+                       what would otherwise be a large number of cross-thread 
messages, requiring relatively expensive mutex protection.
+ */

Index: ACT/Handle.cpp
===================================================================
RCS file: ACT/Handle.cpp
diff -N ACT/Handle.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ACT/Handle.cpp      10 Jul 2007 14:09:08 -0000      1.1
@@ -0,0 +1,91 @@
+// 
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of GNU Cygnal.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+/**    \file Handle.cpp
+ */
+
+#include "Handle.hpp"
+
+namespace ACT {
+       //---------------
+       template< class T, template< class, class > class Aspect >
+       typename Handled< T, Aspect >::registry_type
+       Handled< T, Aspect >::our_registry ;
+
+       //---------------
+       template< class T, template< class, class > class Aspect >
+       typename Handle_Registry_Leader< T, Aspect >::handle_type
+       Handle_Registry_Leader< T, Aspect >::
+       add( T * that )
+       {
+               handle_type x( 0 ) ;
+               if ( free_handles.empty() ) {
+                       // Assert no existing space in registry vector
+                       x = handle_type( the_registry.size() ) ;
+                       the_registry.push_back( that ) ;
+                       aspect.add_in_new_place() ;
+               } else {
+                       // Assert there's an existing slot in the registry 
vector
+                       x = free_handles.back() ;
+                       free_handles.pop_back() ;
+                       the_registry[ x ] = that ;
+                       aspect.add_in_old_place() ;
+               }
+               return x ;
+       }
+
+       template< class T, template< class, class > class Aspect >
+       void
+       Handle_Registry_Leader< T, Aspect >::
+       remove( handle_type x )
+       {
+               try {
+                       // Zero out the entry so that a bad index (however that 
might happen) doesn't get reused.
+                       the_registry.at( x ) = 0 ;
+                       free_handles.push_back( x ) ;
+               } catch ( ... ) {
+               }
+       }
+
+       //---------------
+       template< class T, class Leader, template< class, class, class > class 
Aspect >
+       typename Handle_Registry_Follower< T, Leader, Aspect >::reference 
+       Handle_Registry_Follower< T, Leader, Aspect >::
+       operator[]( handle_type x )
+       {
+               if ( x >= the_registry.size() ) {
+                       if ( x >= the_registry.capacity() ) {
+                               // Assert the handle is outside of the 
allocated bounds of the registry vector.
+                               // Force a reservation, not knowing how 
resize() works.
+                               the_registry.reserve( x + 1 ) ;
+                               aspect.expand_capacity_of_vector() ;
+                       }
+                       // Assert the handle is within the allocated size of 
the registry vector.
+                       the_registry.resize( x + 1 ) ;
+                       aspect.enlarge_size_of_vector() ;
+               } else {
+                       // Assert the handle is already within the bounds of 
the present vector.
+               }
+               // Assert handle is within range of 
+               aspect.access_from_existing_slot() ;
+               return the_registry[ x ] ;
+       }
+
+} // end of namespace ACT

Index: ACT/Handle.hpp
===================================================================
RCS file: ACT/Handle.hpp
diff -N ACT/Handle.hpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ACT/Handle.hpp      10 Jul 2007 14:09:08 -0000      1.1
@@ -0,0 +1,332 @@
+// 
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of GNU Cygnal.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+/**    \file Handle.hpp
+ *     \brief A handle is a type-safe, encapsulated integer that's opaque to 
its ordinary users.
+ *             A handled class is one whose constructor adds it to a singleton 
registry,
+ *                     allowing handles rather than pointers where appropriate.
+ */
+
+#pragma once
+#ifndef __Handle_hpp___
+#define __Handle_hpp___
+
+#include "Aspect.hpp"
+#include <vector>
+
+namespace ACT {
+       //-------------------------
+       /**     \class Handle
+        *      \brief A marked, encapsulate ordinal, used as an index in 
offset operations.
+        *
+        *      - template parameter \c T: parametric so it can match both 
<tt>std::vector< X >::size_type</tt> and others
+        *      - template parameter \c Marker: creates type-distinction to 
prevent intermixing of indices
+        *
+        *      \pre
+        *      - class T is an integral type
+        */
+       template< class T, class Marker >
+       class Handle
+       {
+               // friend classes
+               template< class T, class Marker > friend class 
Vector_with_Handle_Index ;
+
+               /// A handle is an encapsulated integral type
+               T the_index ;
+
+               /// Unwrapper is friends-only
+               inline T get() { return the_index ; }
+       public:
+               /// Expose Marker so that multiple vectors can share a common 
handle type
+               typedef Marker marker_type ;
+
+               /// Explicit constructor is required to avoid accidental 
indexing into non-compatible objects.
+               explicit Handle( T x )
+                       : the_index( x ) {}
+
+               inline bool operator<( Handle & x ) { return the_index < 
x.the_index ; }
+               inline bool operator<=( Handle & x ) { return the_index <= 
x.the_index ; }
+               inline bool operator==( Handle & x ) { return the_index == 
x.the_index ; }
+               inline bool operator>=( Handle & x ) { return the_index >= 
x.the_index ; }
+               inline bool operator>( Handle & x ) { return the_index > 
x.the_index ; }
+               inline bool operator!=( Handle & x ) { return the_index != 
x.the_index ; }
+
+               /// Addition is not Handle-to-Handle, but Handle-to-integer, 
because Handle is ordinal.
+               inline Handle operator+( unsigned int n ) { return Handle( 
the_index + n ) ; }
+       } ;
+
+       //-------------------------
+       /**     \class Vector_with_Handle_Index
+        *      \brief A wrapper around std::vector, with its integral index 
replaced by a handle.
+        */
+       template< class T, class Marker >
+       class Vector_with_Handle_Index
+               : public std::vector< T >
+       {
+               typedef std::vector< T > Base ;         /// Our base class, 
defined for legibility.
+               inline reference operator[]( size_type n ) { throw 
std::exception() ; }                         /// Prohibit offset operation with 
unwrapped index
+               inline const_reference operator[]( size_type n ) const { throw 
std::exception() ; }     /// Prohibit offset operation with unwrapped index
+               inline reference at( size_type n ) { throw std::exception() ; } 
                                        /// Prohibit offset operation with 
unwrapped index
+               inline const_reference at( size_type n ) const { throw 
std::exception() ; }                     /// Prohibit offset operation with 
unwrapped index
+               inline void resize( size_type, T ) { throw std::exception() ; } 
                /// Prohibit resize operation with unwrapped index
+               inline void reserve( size_type ) { throw std::exception() ; }   
                /// Prohibit reserve operation with unwrapped index
+
+       public:
+               /// Declaration of index type
+               typedef Handle< size_type, Marker > handle_type ;
+
+               inline reference operator[]( handle_type n ) { return 
Base::operator[]( n.get() ) ; }                           /// Replacement 
unchecked offset operator
+               inline const_reference operator[]( handle_type n ) const { 
return Base::operator[]( n.get() ) ; }       /// Replacement unchecked offset 
operator
+               inline reference at( handle_type n ) { return Base::at( n.get() 
) ; }                                                           /// Replacement 
checked offset operator
+               inline const_reference at( handle_type n ) const { return 
Base::at( n.get() ) ; }                                       /// Replacement 
checked offset operator
+
+               inline handle_type size() const { return handle_type( 
Base::size() ) ; }                                                        /// 
Replacement size returning handle
+               inline void resize( handle_type n, T val = T() ) { return 
Base::resize( n.get(), val ) ; }                      /// Replacement resize 
with handle
+               inline void reserve( handle_type n ) { return Base::reserve( 
n.get() ) ; }                                                      /// 
Replacement reserve with handle
+               inline handle_type capacity() const { return handle_type( 
Base::capacity() ) ; }                                        /// Replacement 
capacity returning handle
+       } ;
+
+       //-------------------------
+       template< class T, template< class, class > class > class Handled ;
+       //-------------------------
+       /**     \class Handle_Registry_Leader
+        *      \brief A registry that maps handles to instances of a handled 
class.
+        *
+        *      This registry is the normative one.
+        *      Each instance of a class with a handle (that is, deriving from 
\c Handled) appears within this registry.
+        *      In other words, this registry provides a mechanism for 
operationalizing the referent of a handle.
+        */
+       template< class T, template< class, class > class Aspect = 
Null_Aspect_1 >
+       class Handle_Registry_Leader
+       {
+               /// The aspect type as actually used.
+               typedef Aspect< T, Handle_Registry_Leader > aspect_type ;
+
+               /// The aspect class is a friend
+               friend class aspect_type ;
+
+               /// The cooperative Handled aspect is also a friend.
+               friend typename Handled< T, Aspect >::aspect_type ;
+
+               /// Type declaration of the class registry
+               typedef Vector_with_Handle_Index< T *, Handle_Registry_Leader > 
vector_type ;
+
+       public:
+               /// Proxy the declaration of handle type.
+               typedef typename vector_type::handle_type handle_type ;
+
+       private:
+               /// Vector holding pointers to constructed items.
+               vector_type the_registry ;
+
+               /// Stack of free indices
+               std::vector< handle_type > free_handles ;
+
+               /// Aspect instance
+               aspect_type aspect ;
+
+       public:
+               /// Default constructor
+               Handle_Registry_Leader( aspect_type aspect = aspect_type() )
+                       : aspect( aspect )
+               {}
+
+               /// Add an object to the registry, returning its handle.
+               handle_type add( T * ) ;
+
+               /// Remove a handle from the registry.
+               void remove( handle_type ) ;
+
+               /// Offset access is simple because this class issues all its 
own indices.
+               inline T * operator[]( handle_type x ) { return the_registry[ x 
] ; }
+       } ;
+}
+
+namespace aspect {
+       //-------------------------
+       /**     Null_Aspect_1
+        *      \brief Partial specialization of generic aspect holds the hooks 
for derived aspects
+        */
+       template< class T >
+       class Null_Aspect_1< T, ACT::Handle_Registry_Leader< T, Null_Aspect_1 > 
>
+       {
+       public:
+               /// Called in \c Handle_Registry_Leader::add upon successful 
addition that expands the internal size of the registry
+               void add_in_new_place() {}
+
+               /// Called in \c Handle_Registry_Leader::add upon successful 
addition that reuses an existing entry within the registry
+               void add_in_old_place() {}
+       } ;
+}
+
+namespace ACT {
+       //-------------------------
+       /**     \class Handle_Registry_Follower
+        *      \brief A registry indexed by handles issued by a 
Handle_Registry_Leader
+        */
+       template< class T, class Leader, template< class, class, class > class 
Aspect = aspect::Null_Aspect_2 >
+       class Handle_Registry_Follower
+       {
+               /// The aspect type as actually used.
+               typedef Aspect< T, Leader, Handle_Registry_Follower > 
aspect_type ;
+
+               /// The aspect class is a friend
+               friend class aspect_type ;
+
+               /// Marker class derived from Leader
+               typedef typename Leader::handle_type::marker_type marker_type ;
+
+               /// Type declaration of the class registry
+               typedef Vector_with_Handle_Index< T, marker_type > vector_type ;
+
+               /// Vector holding pointers to constructed items.
+               vector_type the_registry ;
+
+       public:
+               /// Proxy the declaration of handle type.
+               typedef typename vector_type::handle_type handle_type ;
+
+               /// Aspect instance
+               aspect_type aspect ;
+
+       public:
+               /// Default constructor
+               Handle_Registry_Follower( aspect_type aspect = aspect_type() )
+                       : aspect( aspect )
+               {}
+
+               /// Reference to content item of this registry
+               typedef typename vector_type::reference reference ;
+
+               /// Offset access for follower requires a possible expansion of 
the internal registry for an as-yet-unseen index.
+               reference operator[]( handle_type x ) ;
+       } ;
+}
+namespace aspect {
+       //-------------------------
+       /**     Null_Aspect_2
+        *      \brief Partial specialization of generic aspect holds the hooks 
for derived aspects
+        */
+       template< class T, class Leader >
+       class Null_Aspect_2< T, Leader, ACT::Handle_Registry_Follower< T, 
Leader, Null_Aspect_2 > >
+       {
+       public:
+               inline void access_from_existing_slot() {} ;
+               inline void expand_capacity_of_vector() {} ;
+               inline void enlarge_size_of_vector() {} ;
+       } ;
+}
+namespace ACT {
+       //-------------------------
+       /**     \class Handled
+        *      \brief A base class for handled classes.
+        *              To use, use the derived class as the template 
parameter, as follows:
+        *              class X : public class Handled< X > { ... } ;
+        *
+        *      This class has the responsibility of defining a class registry 
for each class T.
+        */
+       template< class T, template< class, class > class Aspect = 
aspect::Null_Aspect_1 >
+       class Handled
+       {
+       public:
+               /// The aspect type as actually used.
+               typedef Aspect< T, Handled > aspect_type ;
+
+               /// The aspect class is a friend
+               friend class aspect_type ;
+
+       private:
+               /// Type declaration of the class registry
+               typedef Handle_Registry_Leader< T, Aspect > registry_type ;
+
+               /// Per-class registry.
+               ///
+               ///     [EH 2007-06-25]
+               ///     In MSVC8, this declaration must appear after that for 
\c aspect_type,
+               ///             otherwise the compiler says it's not defined in 
this class.
+               /// This is a compiler defect.
+               /// The point of instantiation is supposed to be immediately 
before the declaration containing the first instance,
+               ///             but at a namespace or global level, not within 
a class declaration.
+               /// That means that \c registry_type is supposed to be 
instantiated before this class is.
+               /// Since visibility has an ordering dependence, I conclude the 
class is not instantiated then, 
+               ///             immediately before this class, but rather 
within the class.
+               /// In other words, MSVC8 has their point of instantiation 
wrong.
+               static registry_type our_registry ;
+
+       public:
+               /// Proxy the declaration of handle type from registry type.
+               typedef typename registry_type::handle_type handle_type ;
+
+       private:
+               /// Enclosed handle 
+               handle_type the_handle ;
+
+       protected:
+               /// Aspect helper instance.
+               ///
+               /// It's protected so that derived classes may access the 
aspect.
+               /// This class is designed to be a base class, so this is a 
generic need.
+               /// If a read-only version of the aspect is desired, 
+               ///             change the access control of this item to 
private
+               ///             and add a \c const accessor function returning 
a reference.
+               aspect_type aspect ;
+
+       public:
+               /// Default constructor takes as parameter the \c this pointer 
of a derived object.
+               Handled( T * that, aspect_type aspect = aspect_type() )
+                       : the_handle( our_registry.add( that ) ),
+                       aspect( aspect )
+               {
+                       aspect.set_owner( this ) ;
+               }
+
+               /// Destructor
+               ~Handled() { our_registry.remove( the_handle ) ; }
+
+               /// Class method to access registry
+               static T * registry_at( handle_type x ) { return our_registry[ 
x ] ; }
+
+               /// Handle accessor
+               inline handle_type handle() const { return the_handle ; }
+       } ;
+
+       //-------------------------
+       /**     \class Null_Aspect_Handled
+        *      \brief Base for aspect classes of \c Handled
+        */
+       template< class T >
+       class Null_Aspect_Handled
+       {} ;
+
+} // end of namespace ACT
+
+namespace aspect {
+       //-------------------------
+       /**     Null_Aspect_1
+        *      \brief Default null aspect class, bound through default aspect 
parameter
+        */
+       template< class T >
+       class Null_Aspect_1< T, ACT::Handled< T, Null_Aspect_1 > >
+               : public ACT::Null_Aspect_Handled< T >,
+               public Null_Aspect_Base< ACT::Handled< T, Null_Aspect_1 > >
+       {} ;
+}
+
+#endif // end of inclusion protection

Index: ACT/Listen.T.cpp
===================================================================
RCS file: ACT/Listen.T.cpp
diff -N ACT/Listen.T.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ACT/Listen.T.cpp    10 Jul 2007 14:09:08 -0000      1.1
@@ -0,0 +1,99 @@
+// 
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of GNU Cygnal.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+/// \file Listen.T.cpp
+/// \brief Implementations of a set of simple actions with which to test the 
scheduler
+
+#include "Listen.hpp"
+
+namespace ACT {
+       //--------------------------------------------------
+       // Basic_Listen_Monitor
+       //--------------------------------------------------
+       template< class Listener >
+       void
+       Basic_Listen_Monitor< Listener >::
+       add_ready_listener_task( wakeup_listener * w )
+       {
+               ready_list.push_back( w ) ;
+       }
+
+       template< class Listener >
+       ACT_State
+       Basic_Listen_Monitor< Listener >::
+       wake_up_ready_tasks()
+       {
+               if ( ready_list.empty() ) {
+                       // This monitor is no longer necessary, since there's 
nothing to wake up.
+                       // Therefore we return complete and let the scheduler 
remove this instance.
+                       // We first have to remove ourselves from the follower 
registry, in order to be re-created when needed.
+
+                       // Note that we only return Completed when the ready 
list is empty at the start of execution.
+                       // This satisfies the service requirement 
+                       //              that a service action may not both 
reschedule a task and complete itself in the same invocation.
+                       return set_completed() ;
+               }
+               do {
+                       ( * ready_list.back() )() ;
+                       ready_list.pop_back() ;
+               } while ( ! ready_list.empty() ) ;
+               return set_ready() ;
+       }
+
+       //--------------------------------------------------
+       // Basic_Listening_Task
+       //--------------------------------------------------
+       // Class registry definition
+       template< class Listener, class Monitor >
+       typename Basic_Listening_Task< Listener, Monitor 
>::follower_registry_type
+       Basic_Listening_Task< Listener, Monitor >::schedulers ;
+
+       //-------------------------
+       template< class Listener, class Monitor >
+       void
+       Basic_Listening_Task< Listener, Monitor >::
+       register_for_wakeup( Listener * that, wakeup_listener * w )
+       {
+               if ( w == 0 ) return ;
+               // Assert wakeup listener is non-trivial.
+
+               handle_type k = w -> scheduler() -> handle() ;
+               // Assert k is the handle to the scheduler of origin for our 
wakeup_listener
+               shared_ptr< monitor_type > p = schedulers[ k ].lock() ;
+               // Assert p is the monitor associated with our scheduler, if 
one exists.
+
+               // Ensure monitor exists
+               if ( ! p ) {
+                       // Assert monitor does not yet exist
+                       p = shared_ptr< monitor_type >( new monitor_type() ) ;
+                       schedulers[ k ] = boost::weak_ptr< monitor_type >( p ) ;
+                       // Monitor exists but it's not yet scheduled (invariant 
violation)
+                       w -> scheduler() -> add_service( act( p ) ) ;
+                       // Assert monitor exists in registry and it's scheduled 
(invariant satisfied)
+               }
+               // Assert listening monitor for this class exists
+               // Assert p == schedulers[ k ].lock() && p != 0
+
+               // Add the current instance to the monitor associated with our 
wakeup listener
+               p -> add_wakeup_item( that, w ) ;
+       }
+
+       //-------------------------
+} // end namespace ACT
\ No newline at end of file

Index: ACT/Listen.hpp
===================================================================
RCS file: ACT/Listen.hpp
diff -N ACT/Listen.hpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ACT/Listen.hpp      10 Jul 2007 14:09:08 -0000      1.1
@@ -0,0 +1,138 @@
+// 
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of GNU Cygnal.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+/// \file Listen.hpp
+
+#pragma once
+#ifndef __Listen_hpp__
+#define __Listen_hpp__
+
+#include "ACT/Scheduler.hpp"
+#include "ACT/Handle.hpp"
+
+#include <boost/weak_ptr.hpp>
+#include <vector>
+
+namespace ACT {
+       //-------------------------
+       /**     \class Basic_Listen_Monitor
+        *      \brief Base class for monitor service actions.
+        *
+        *      Collaborators:
+        *              - Basic_Listening_Task. Tasks register themselves here 
when they need to wake up.
+        *              - Scheduler. This action runs as a service within the 
scheduler.  
+        *                      While this class uses no specific knowledge of 
its scheduler, it satisfies the requirements for a service action.
+        *              - wakeup_listener.  Calls this is a function object to 
effect a wake-up.
+        *      Responsibilities:
+        *              - Hold a record of each task that is waiting and won't 
again run until this class wakes it up.
+        *              - Run as a service in the same scheduler that each task 
is also in.
+        *              - When activated, wake up waiting tasks that have 
become ready.
+        *                      Note: this is not a postcondition for monitors 
generally.
+        *                      A monitor might only wake up a subset of its 
ready tasks at each activation.
+        */
+       template< class Listener >
+       class Basic_Listen_Monitor
+               : public simple_act
+       {
+               /// Container for actions ready to run.
+               ///
+               /// \par Future
+               ///             The vector used currently will be replaced by 
one provided by the scheduling queue.
+               ///             Since each task is present in at most one 
monitor list,
+               ///                     we may eliminate an entire dynamic 
allocation issue by allocating them within the scheduling queue.
+               std::vector< wakeup_listener * > ready_list ;
+
+       protected:
+               /// Run through the ready list and wake up all the tasks on it, 
removing them from the ready list.
+               ///
+               /// This is typically the last statement in the action body of 
a derived monitor.
+               /// \post
+               ///     - return value is either Completed or Working
+               ACT_State wake_up_ready_tasks() ;
+
+               /// Add an item directly to the ready list, skipping readiness 
checking
+               ///
+               /// Since the item is known to be ready, it needs no further 
examination.
+               /// It need not appear in the parameter list, in 
contradistinction to \c add_waiting_listener_task.
+               void add_ready_listener_task( wakeup_listener * ) ;
+
+               /// Add an item to the waiting list
+               void add_waiting_listener_task( Listener *, wakeup_listener * ) 
;
+       } ;
+
+       //-------------------------
+       /**     \class Basic_Listening_Task
+        *      \brief Base class for tasks that may suspend themselves and 
listen for wakeup.
+        *
+        *      Collaborators:
+        *              - Basic_Listen_Monitor. An instance registers itself 
with its monitor, upon which it relies for wake-up.
+        *              - Scheduler. This action runs as a task within the 
scheduler.  
+        *      Responsibilities.
+        *              - Register self for later wake-up if it suspends 
computation.
+        */
+       template< class Listener, class Monitor >
+       class Basic_Listening_Task
+               : public autonomous_act
+       {
+               /// The monitor type for these actions to register with.
+               typedef Monitor monitor_type ;
+
+               /// Type of handles to Scheduler
+               typedef Scheduler::handle_type handle_type ;
+
+               /// Type of the class registry of monitors
+               typedef typename Handle_Registry_Follower< boost::weak_ptr< 
Monitor >, Scheduler > follower_registry_type ;
+
+               /**     A vector of monitors, indexed by Scheduler handles.
+                *
+                *      The cardinality relationship is either zero-or-one 
monitor instance for each scheduler.
+                *
+                *      \invariant
+                *      - Each monitor within this registry is present in the 
queue of its corresponding scheduler.
+                *
+                *      Occurrences when this invariant might be violated:
+                *      - When adding a monitor as a service, the add_service 
call in the registry doesn't know about the registry.
+                *              Therefore, we add it to the registry when 
adding a listening monitor service.
+                *      - When a monitor completes (say, having nothing left to 
listen for), the scheduler remove it from the queue.
+                *              Therefore, when a monitor completes, it's 
shared_ptr in the Scheduler goes away,
+                *                      so the weak_ptr in the follower 
registry expires.
+                *      - When a registry terminates, it might do so with 
pending actions in its queue.
+                *              While this is abnormal, it may also be 
recoverable with a single execution context.
+                *              The entire scheduling queue in terminated 
scheduler goes out of scope,
+                *                      so, as with ordinary monitor 
completion, the weak_ptr expires.
+                *              Unlike the case of ordinary monitor completion, 
the destructor for the scheduler
+                *                      runs before that of the monitor.
+                *              Since the monitor is ignorant of its scheduler, 
this makes no difference.
+                */
+               static follower_registry_type schedulers ;
+
+       protected:
+               /**     \brief Register an action for wakeup
+                *      \post
+                *      - Monitor is registered in the scheduler and will 
eventually run.
+                */
+               void register_for_wakeup( Listener * that, wakeup_listener * w 
) ;
+
+       } ;
+
+       //-------------------------
+} // end namespace ACT
+
+#endif

Index: ACT/Pause_Demon.cpp
===================================================================
RCS file: ACT/Pause_Demon.cpp
diff -N ACT/Pause_Demon.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ACT/Pause_Demon.cpp 10 Jul 2007 14:09:08 -0000      1.1
@@ -0,0 +1,48 @@
+// 
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of GNU Cygnal.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+/// \file Pause_Demon.cpp
+///    \brief The Pause service suspends itself (and its thread) for a number 
of milliseconds 
+///            if the scheduling queue has no high-priority items.
+
+#include "Pause_Demon.hpp"
+#include <boost/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+
+namespace ACT {
+       //-------------------------
+       ACT_State
+       Pause_Demon::
+       run()
+       {
+               if ( the_scheduler -> ordinary_tasks_available() )
+                       return ACT_State::Ready ;
+
+               boost::xtime t ;
+               if ( 0 == xtime_get( & t, boost::TIME_UTC ) ) {
+                       return set_bad() ;
+               }
+               t.nsec += ms_to_pause * 1000 * 1000 ;
+               boost::thread().sleep( t ) ;
+               return ACT_State::Ready ;
+       }
+
+       //-------------------------
+} // end namespace ACT

Index: ACT/Pause_Demon.hpp
===================================================================
RCS file: ACT/Pause_Demon.hpp
diff -N ACT/Pause_Demon.hpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ACT/Pause_Demon.hpp 10 Jul 2007 14:09:08 -0000      1.1
@@ -0,0 +1,77 @@
+// 
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of GNU Cygnal.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+/// \file Pause_Demon.hpp
+///    \brief The Pause service suspends itself (and its thread) for a number 
of milliseconds 
+///            if the scheduling queue has no high-priority items.
+
+#pragma once
+#ifndef __Pause_Demon_hpp__
+#define __Pause_Demon_hpp__
+
+#include "ACT.hpp"
+#include "Scheduler.hpp"
+
+namespace ACT {
+       //-------------------------
+       /**     \class Pause_Demon
+        *      \brief A service that does nothing for some number of 
milliseconds if the scheduler has no tasks pending.
+        *
+        *      This service is only pauses during quiet or quiescent operation 
of a scheduler.
+        *      The point is to reduce CPU load when nothing is happening.
+        *      This class is not the most efficient for a low-load service, 
+        *              since it consumes some constant fraction of CPU 
regardless of other load.
+        *      At high load, this service consumes neglible CPU.
+        *
+        *      \par Future
+        *      For low-load and/or utility server applications, this service 
should be replaced with one that simply blocks.
+        *      Such a service would have to cooperate with all other listening 
facilities, any of which could unblock it.
+        *
+        *      \par Defects
+        *      - The present implementation is immortal, preventing graceful 
cooperative shutdown.
+        *              It should be able to terminate itself under at least 
one condition.
+        *              For example, if no other tasks or services are present, 
then this one too can end.
+        */
+       class Pause_Demon
+               : public simple_act
+       {
+               /// Configuration parameter.
+               ///
+               /// Should eventually transition to a template parameter.
+               static const unsigned int ms_to_pause = 20 ;
+
+               /// Action body.
+               ACT_State run() ;
+
+               /// Scheduler determines whether pause is necessary or not.
+               Scheduler * the_scheduler ;
+
+       public:
+               /// 
+               Pause_Demon( Scheduler * sc )
+                       : the_scheduler( sc )
+               {}
+
+       } ;
+
+       //-------------------------
+} // end namespace ACT
+
+#endif
\ No newline at end of file

Index: ACT/Scheduler.T.cpp
===================================================================
RCS file: ACT/Scheduler.T.cpp
diff -N ACT/Scheduler.T.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ACT/Scheduler.T.cpp 10 Jul 2007 14:09:08 -0000      1.1
@@ -0,0 +1,163 @@
+// 
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of GNU Cygnal.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+/// \file Scheduler.T.cpp
+
+#include "Scheduler.hpp"
+
+namespace ACT {
+       //--------------------------------------------------
+       // wakeup_listener_allocated
+       //--------------------------------------------------
+       template< class S >
+       wakeup_listener_allocated< S >::
+       wakeup_listener_allocated( size_t x, scheduler_pointer y )
+               : the_wakeup_listener( new Basic_Wakeup_Listener< S >( x, y ) ) 
{}
+
+       //--------------------------------------------------
+       // Basic_Wakeup_Listener
+       //--------------------------------------------------
+       template< class S >
+       void
+       Basic_Wakeup_Listener< S >::
+       operator()()
+       {
+               queue_type & the_queue = the_scheduler -> queue() ;
+               the_queue.item( permutation_index ).priority_category = 
Ordinary ;
+               the_queue.reorder( permutation_index ) ;
+       }
+
+       //--------------------------------------------------
+       // Basic_Scheduler
+       //--------------------------------------------------
+       template< template< class > class Aspect >
+       Basic_Scheduler< Aspect >::
+       Basic_Scheduler( aspect_type aspect )
+               : Scheduler( this ),
+               operating( true ),
+               next_task_sequence_number( 1 ),
+               next_service_sequence_number( 1 ),
+               aspect( aspect )
+       {
+               aspect.set_owner( this ) ;
+       }
+
+       //-------------------------
+       template< template< class > class Aspect >
+       void
+       Basic_Scheduler< Aspect >::
+       reset()
+       {
+               operating = true ;
+       }
+
+       //-------------------------
+       template< template< class > class Aspect >
+       void
+       Basic_Scheduler< Aspect >::
+       operator()()
+       {
+               aspect.run_begin() ;
+               while ( operating ) {
+                       if ( ! aspect.run_guard() ) {
+                               aspect.run_end_guard_violation() ;
+                               return ;
+                       }
+                       activate_one_item() ;
+               }
+               aspect.run_end_ordinary() ;
+       }
+
+       //-------------------------
+       template< template< class > class Aspect >
+       void
+       Basic_Scheduler< Aspect >::
+       add_task( act x )
+       {
+               item_pointer item = the_queue.push( Basic_Scheduled_Item( x, ++ 
next_task_sequence_number ), this ) ;
+       }
+
+       template< template< class > class Aspect >
+       void
+       Basic_Scheduler< Aspect >::
+       add_service( act x )
+       {
+               item_pointer item = the_queue.push( Basic_Scheduled_Item( x, ++ 
next_service_sequence_number, Demon ), this ) ;
+       }
+
+       template< template< class > class Aspect >
+       void
+       Basic_Scheduler< Aspect >::
+       add_critical_service( act )
+       {
+       }
+
+       //-------------------------
+       template< template< class > class Aspect >
+       void
+       Basic_Scheduler< Aspect >::
+       activate_one_item()
+       {
+               // Note that this operation is not locked.
+               // As of this version, this is a single-threaded server.
+               if ( the_queue.empty() ) {
+                       // If the queue is finally empty, we're done.
+                       operating = false ;
+                       return ;
+                       // An alternate behavior would be to wait indefinitely 
for another scheduled item.
+                       // This is an asynchronous scheduler; it doesn't wait.
+                       // To understand how this scheduler wakes up from 
quiescence, look into service actions.
+               }
+               // Assert the_queue is not empty
+
+               queue_type::pointer item = the_queue.top_ptr() ;
+               ACT_State result = item -> the_action( 
the_queue.auxiliary_top() -> get() ) ;
+               if ( result.working() ) {
+                       switch ( item -> action_type ) 
+                       {
+                               case Task :
+                                       // Assert action is not a service
+                                       item -> priority_category = Waiting ;
+                                       the_queue.reorder( item ) ;
+                                       break ;
+                               case Demon :
+                                       // Always reset the sequence number for 
a demon.
+                                       // The resulting behavior is to cycle 
through all available demons.
+                                       item -> sequence_number = 
next_service_sequence_number ++ ;
+                                       the_queue.reorder( item ) ;
+                                       break ;
+                       }
+               } else {
+                       the_queue.pop() ;
+                       // Perhaps we might want to log items gone bad here.
+               }
+       }
+
+       //-------------------------
+       template< template< class > class Aspect >
+       bool
+       Basic_Scheduler< Aspect >::
+       ordinary_tasks_available()
+       {
+               if ( the_queue.empty() ) return false ;
+               return the_queue.top().priority_category <= Ordinary ;
+       }
+
+} // end namespace ACT

Index: ACT/test_support/Supplied_Service.cpp
===================================================================
RCS file: ACT/test_support/Supplied_Service.cpp
diff -N ACT/test_support/Supplied_Service.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ACT/test_support/Supplied_Service.cpp       10 Jul 2007 14:09:09 -0000      
1.1
@@ -0,0 +1,57 @@
+// 
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of GNU Cygnal.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+/// \file Supplied_Service.cpp
+/// \brief A service that takes an outside supply of actions and supplies them 
as a service.
+
+#include "Supplied_Service.hpp"
+
+namespace ACT {
+       shared_ptr< basic_act >
+       Supplied_Generator::
+       next_action( wakeup_listener * )
+       {
+               if ( ! complete ) {
+                       if ( ! the_tasks.empty() ) {
+                               shared_ptr< basic_act > x = the_tasks.front() ;
+                               the_tasks.pop_front() ;
+                               return x ;
+                       } else {
+                               if ( ! active ) complete = true ;
+                       }
+                       /// Assert no more tasks left to return
+               }
+               return shared_ptr< basic_act >() ;
+       }
+
+       void
+       Supplied_Generator::
+       add_task( shared_ptr< basic_act > x )
+       {
+               if ( ! active ) throw std::exception( "Not accepting new 
actions after shutdown" ) ;
+               the_tasks.push_back( x ) ;
+       }
+
+} // end namespace ACT
+
+#include "ACT/Service.cpp"
+namespace ACT {
+       template Service< Supplied_Service_Aspect > ;
+}

Index: ACT/test_support/Supplied_Service.hpp
===================================================================
RCS file: ACT/test_support/Supplied_Service.hpp
diff -N ACT/test_support/Supplied_Service.hpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ACT/test_support/Supplied_Service.hpp       10 Jul 2007 14:09:09 -0000      
1.1
@@ -0,0 +1,121 @@
+// 
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of GNU Cygnal.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+/// \file Supplied_Service.hpp
+/// \brief A service that takes an outside supply of actions and supplies them 
as a service.
+
+#pragma once
+#ifndef __Supplied_Service_hpp__
+#define __Supplied_Service_hpp__
+
+#include "ACT/Service.hpp"
+#include "Action_Tracing.hpp"
+#include <list>
+
+namespace ACT {
+       //-------------------------
+       /**     \class Supplied_Generator
+        *      \brief A generator whose entries are added manually one by one.
+        */
+       class Supplied_Generator
+               : public Generator
+       {
+               /// List of pending actions.
+               std::list< shared_ptr< basic_act > > the_tasks ;
+
+               /// Remove the first pending action in our internal list and 
return it.
+               shared_ptr< basic_act > next_action( wakeup_listener * ) ;
+
+               /// The active-vs.-shutdown state of this generator.
+               bool active ;
+
+               ///
+               bool complete ;
+
+       public:
+               /// Default constructor starts off in active state.
+               Supplied_Generator()
+                       : active( true ), complete( false ) {}
+
+               /// This \c shutdown routine pushes out all pending actions, 
accepting no new ones.
+               void shutdown() { active = false ; }
+
+               ///
+               void add_task( shared_ptr< basic_act > ) ;
+
+               ///
+               bool completed() { return complete ; }
+       } ;
+
+       //-------------------------
+       // Aspect for Service base class
+       template< class > class Supplied_Service_Aspect ;
+
+       //-------------------------
+       //      Supplied_Service_Aspect
+       /**
+        *      \brief Aspect for class \c Service that tracks the run function
+        */
+       template<>
+       class Supplied_Service_Aspect< Service< Supplied_Service_Aspect > >
+               : public Service_Null_Aspect,
+               public aspect::Aspect_Has_Access_To_Owner< Service< 
Supplied_Service_Aspect > >
+       {
+               /// Tracking
+               std::auto_ptr< tracking_function > tracker ;
+
+       public:
+               Supplied_Service_Aspect( tracking_function * t )
+                       : tracker( t )
+               {}
+
+               void log_run_begin() { if ( tracker.get() != 0 ) ( * tracker )( 
"" ) ; }
+       } ;
+
+       //-------------------------
+       /**     \class Supplied_Service
+        *      \brief A service whose tasks are manually added one by one.
+        */
+       class Supplied_Service
+               : public Service< Supplied_Service_Aspect >
+       {
+               /// Aspect type for \c Service base class
+               typedef Supplied_Service_Aspect< Service< 
Supplied_Service_Aspect > > service_base_aspect_type ;
+
+               /// Member allocation for our generator
+               Supplied_Generator the_generator ;
+
+       public:
+               /// Default constructor
+               Supplied_Service( Scheduler & z, tracking_function * t = 0 )
+                       : Service( the_generator, z, service_base_aspect_type( 
t ) )
+               {}
+
+               ///
+               inline void shutdown() { the_generator.shutdown() ; }
+
+               ///
+               inline void add_task( shared_ptr< basic_act > x ) { 
the_generator.add_task( x ) ; }
+       } ;
+
+       //-------------------------
+} // end namespace ACT
+
+#endif

Index: HTTP/Change_Log.txt
===================================================================
RCS file: HTTP/Change_Log.txt
diff -N HTTP/Change_Log.txt
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ HTTP/Change_Log.txt 10 Jul 2007 14:09:10 -0000      1.1
@@ -0,0 +1,6 @@
+Change Log for GNU Cygnal, Module HTTP
+======================================
+
+2007-07-09 Eric Hughes <address@hidden>
+       * unit_tests/Test_HTTP.cpp: Duplicated Invalid_Version_Request test 
into ordinary URI and *-URI forms.
+       * HTTP_Parse.[hc]pp: Fixed defect in Request_Scanner, which wasn't 
looking explicitly for a space after the URI.  It was relying on the URI 
scanner to consume the next character, but since the URI scanner is used 
elsewhere, it should not silently consume anything other than the URI itself.  
Fixing this defect allowed the Invalid_Version_Request, *-version, to pass, but 
unmasked the defect in URI scanning.

Index: Net/Change_Log.txt
===================================================================
RCS file: Net/Change_Log.txt
diff -N Net/Change_Log.txt
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ Net/Change_Log.txt  10 Jul 2007 14:09:11 -0000      1.1
@@ -0,0 +1,5 @@
+Change Log for GNU Cygnal, Module Net
+=====================================
+
+2007-07-06 Eric Hughes <address@hidden>
+       * socket_device.cpp: Stubbed out obsolete reaction to EINTR.

Index: Aspect.hpp
===================================================================
RCS file: Aspect.hpp
diff -N Aspect.hpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ Aspect.hpp  10 Jul 2007 14:09:11 -0000      1.1
@@ -0,0 +1,135 @@
+// 
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of GNU Cygnal.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+/**    \file Aspect.hpp
+ *     \brief An aspect is a hook for augmenting the behavior of a class at 
compile time.
+ */
+
+#pragma once
+#ifndef __Aspect_hpp___
+#define __Aspect_hpp___
+
+namespace aspect {
+
+       //--------------------------------------------------
+       // Base null aspect classes for specialization
+
+       /// Base Null_Aspect class for class that would otherwise be ordinary 
classes (no template)
+       template< class Owner >
+       class Null_Aspect_0 
+       {} ;
+
+       /// Base Null_Aspect class for class that would otherwise have a single 
template parameter
+       template< class T, class Owner >
+       class Null_Aspect_1
+       {} ;
+
+       /// Base Null_Aspect class for class that would otherwise have two 
template parameters
+       template< class T1, class T2, class Owner >
+       class Null_Aspect_2
+       {} ;
+
+       //--------------------------------------------------
+       /**     \class Null_Aspect_Base
+        *
+        *      Specializations of null aspect templates, required to create 
hook points, do not inherit from their generic template.
+        *      This class provides such a base.
+        *      In order that null templates may derive from it, it does not 
define any data.
+        *
+        *      This base is needed to provide a null definition of the hooks 
provided by other add-in classes within this module.
+        *      The first one of these is \c set_owner(), needed for an aspect 
to gain access its owner's internal data.
+        *      When other add-ins are defined, put a null function definition 
here for each function in the add-in.
+        */
+       template< class Owner >
+       class Null_Aspect_Base
+       {
+       public:
+               /// The owner type is the class of which this class is an 
aspect.
+               typedef Owner owner_type ;
+
+               /// For the null aspect set_owner does nothing.
+               inline void set_owner( Owner * x ) {}
+       } ;
+
+       //--------------------------------------------------
+       /** \class Aspect_Has_Access_To_Owner
+        *      \brief Base class for aspects that require access to their 
owner.
+        *
+        *      Not all aspects require access to their owner class.
+        *      Universally, null aspects don't, because the operations they 
define don't do anything.
+        *      Access to an owner requires storing a pointer, so a null aspect 
couldn't have one anyway,
+        *              since a null aspect must not define storage (otherwise 
it's not null).
+        */
+       template< class Owner >
+       class Aspect_Has_Access_To_Owner
+       {
+               /// This class is a wrapper around a pointer to its owner.
+               Owner * the_owner ;
+
+       public:
+               /// Default constructor
+               Aspect_Has_Access_To_Owner()
+                       : the_owner( 0 ) {}
+
+               /// Accessor to owner
+               inline Owner * owner() const { return the_owner ; }
+
+               /// Owner must be set after construction, because 'this' isn't 
known before the aspect instance is constructed.
+               inline void set_owner( Owner * x ) { the_owner = x ; }
+       } ;
+
+       //--------------------------------------------------
+       /** \class Aspect_Has_Const_Access_To_Owner
+        *      \brief Base class for aspects that require read access to their 
owner, but not write access.
+        *
+        *      Not all aspects require access to their owner class.
+        *      Universally, null aspects don't, because the operations they 
define don't do anything.
+        *      Access to an owner requires storing a pointer, so a null aspect 
couldn't have one anyway,
+        *              since a null aspect must not define storage (otherwise 
it's not null).
+        */
+       template< class Owner >
+       class Aspect_Has_Const_Access_To_Owner
+       {
+               /// This class is a wrapper around a pointer to its owner.
+               const Owner * the_owner ;
+
+       public:
+               /// Default constructor
+               Aspect_Has_Const_Access_To_Owner( const Owner * x )
+                       : the_owner( x ) {}
+
+               /// Accessor to owner
+               inline const Owner * owner() const { return the_owner ; }
+       } ;
+
+       //--------------------------------------------------
+       /**
+        */
+} // end namespace aspect
+
+
+// This should move to config.h, perhaps
+#ifdef _MSC_VER
+// Disable the warning about "'this' uses in base member initializer list
+#      pragma warning(disable:4355)
+#else
+#endif
+
+#endif // end of inclusion protection

Index: Change_Log.txt
===================================================================
RCS file: Change_Log.txt
diff -N Change_Log.txt
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ Change_Log.txt      10 Jul 2007 14:09:11 -0000      1.1
@@ -0,0 +1,24 @@
+Change Log for GNU Cygnal
+=========================
+
+2007-07-09 Eric Hughes <address@hidden>
+       * ACT/ACT.hpp: Changed ACT_State::Waiting to Would_Block.  Modified 
convenience methods accordingly.
+       * ACT/Pause_Service.cpp, ACT/test_support/Listening_Actions.cpp, 
HTTP/HTTP_Behavior.cpp: followed ACT.hpp changes.
+       * ACT/unit_tests/Test_ACT.cpp: Improved act_twice to ensure guard on 
run() is in effect.
+       * IO/Stream_Consumer.cpp: Removed defect that was masking failures in 
scanning.  Change causes an HTTP unit test to fail.
+
+2007-07-06 Eric Hughes <address@hidden>
+       * ACT/ACT.hpp: Converted ACT_State from an enumeration to a class.  
Removed convenience typedef.
+       * IO/Stream_Consumer.hpp: Added source_state() to assist in writing 
parsing filters.
+       * Lots and lots of files: Renamed act_state to ACT_State everywhere.  
Changed constant references to Working to either Waiting or Ready, as 
appropriate.  Changed set_working() to set_ready(), set_waiting(), or 
source_state(), as appropriate.
+       
+2007-07-06 Eric Hughes <address@hidden>
+       * doc/Doxyfile: Converted all paths to relative form.
+       * doc/mainpage.doxygen.txt: Wrote new main page.
+       * ACT/ACT.doxygen.txt: Wrote new page with overview of ACT.
+
+2007-06-28 Eric Hughes <address@hidden>
+       * doc/Doxyfile: New file.
+
+2007-06-17 Eric Hughes <address@hidden>
+       * ACT/*: Got listener wakeup working correctly in scheduler.

Index: mainpage.doxygen.txt
===================================================================
RCS file: mainpage.doxygen.txt
diff -N mainpage.doxygen.txt
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ mainpage.doxygen.txt        10 Jul 2007 14:09:12 -0000      1.1
@@ -0,0 +1,36 @@
+/**
+
+\mainpage GNU Cygnal
+
+\section s_Introduction Introduction
+
+       Documentation for the source code of GNU Cygnal.
+       
+\section s_Code_Organization Code Organization
+
+       The code is organized into a set of modules:
+       - \ref ACT.  
+               Asynchronous Computation Task.  
+               The multitasking foundation of the system.
+       - IO. 
+               Input/Output.
+               ACT-enabled I/O infrastructure.
+               Provides scattered buffering and the conversion of asynchronous 
block I/O into an asynchronous stream abstraction.
+       - Net.
+               Network I/O.
+               ACT-enabled network primitives.
+       - HTTP.
+               HTTP syntax and protocol behavior.
+
+\section s_Running_Doxygen Running Doxygen [EH as of 2007-07-05]
+
+       Doxygen doesn't deal so well with code that makes heavy use of 
templates.
+       Here's a <a 
href="http://bugzilla.gnome.org/buglist.cgi?query_format=advanced&short_desc_type=allwordssubstr&short_desc=template&product=doxygen&long_desc_type=substring&long_desc=&status_whiteboard_type=allwordssubstr&status_whiteboard=&keywords_type=allwords&keywords=&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=NEEDINFO&emailassigned_to1=1&emailtype1=substring&email1=&emailassigned_to2=1&emailreporter2=1&emailqa_contact2=1&emailcc2=1&emailtype2=substring&email2=&bugidtype=include&bug_id=&chfieldfrom=&chfieldto=Now&chfieldvalue=&cmdtype=doit&order=Bug+Number&field0-0-0=noop&type0-0-0=noop&value0-0-0=";>search
 for doxygen template defects</a>.
+       While it would be a good thing for doxygen to run without errors, 
that's not happening now.
+       The two most common defects seem to be these:
+               - No recognition of explicit template instantiation: 
http://bugzilla.gnome.org/show_bug.cgi?id=331519.
+               - Conflation of members in template specifications: 
http://bugzilla.gnome.org/show_bug.cgi?id=406027.
+       There are a couple of other errors doxygen spits out.
+       I haven't located them in the doxygen issue tracker.
+
+ */
\ No newline at end of file

Index: doc/Doxyfile
===================================================================
RCS file: doc/Doxyfile
diff -N doc/Doxyfile
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ doc/Doxyfile        10 Jul 2007 14:09:12 -0000      1.1
@@ -0,0 +1,264 @@
+# Doxyfile 1.5.2
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING      = UTF-8
+PROJECT_NAME           = "GNU Cygnal"
+PROJECT_NUMBER         = 
+OUTPUT_DIRECTORY       = doc
+CREATE_SUBDIRS         = YES
+OUTPUT_LANGUAGE        = English
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = YES
+STRIP_FROM_PATH        = 
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+SEPARATE_MEMBER_PAGES  = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+BUILTIN_STL_SUPPORT    = NO
+CPP_CLI_SUPPORT        = NO
+DISTRIBUTE_GROUP_DOC   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = NO
+EXTRACT_STATIC         = NO
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = YES
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = NO
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = NO
+FILE_VERSION_FILTER    = 
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = YES
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file( $line) : $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = .
+INPUT_ENCODING         = UTF-8
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.d \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.doxygen.txt
+RECURSIVE              = YES
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXCLUDE_SYMBOLS        = BOOST_AUTO_UNIT_TEST
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = *
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION    = NO
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS              = NO
+VERBATIM_HEADERS       = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = YES
+TREEVIEW_WIDTH         = 350
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = .
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+MSCGEN_PATH            = 
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+GROUP_GRAPHS           = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+CALLER_GRAPH           = NO
+GRAPHICAL_HIERARCHY    = YES
+DIRECTORY_GRAPH        = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+DOT_GRAPH_MAX_NODES    = 50
+DOT_TRANSPARENT        = NO
+DOT_MULTI_TARGETS      = NO
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO

Index: ACT/Pause_Service.cpp
===================================================================
RCS file: ACT/Pause_Service.cpp
diff -N ACT/Pause_Service.cpp
--- ACT/Pause_Service.cpp       1 Jul 2007 10:53:50 -0000       1.2
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,48 +0,0 @@
-// 
-// Copyright (C) 2007 Free Software Foundation, Inc.
-//
-// This file is part of GNU Cygnal.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-
-/// \file Pause_Service.hpp
-///    \brief The Pause service suspends itself (and its thread) for a number 
of milliseconds 
-///            if the scheduling queue has no high-priority items.
-
-#include "Pause_Service.hpp"
-#include <boost/thread/thread.hpp>
-#include <boost/thread/xtime.hpp>
-
-namespace ACT {
-       //-------------------------
-       act_state
-       Pause_Service::
-       run()
-       {
-               if ( the_scheduler -> ordinary_tasks_available() )
-                       return Working ;
-
-               boost::xtime t ;
-               if ( 0 == xtime_get( & t, boost::TIME_UTC ) ) {
-                       return set_bad() ;
-               }
-               t.nsec += ms_to_pause * 1000 * 1000 ;
-               boost::thread().sleep( t ) ;
-               return Working ;
-       }
-
-       //-------------------------
-} // end namespace ACT

Index: ACT/Pause_Service.hpp
===================================================================
RCS file: ACT/Pause_Service.hpp
diff -N ACT/Pause_Service.hpp
--- ACT/Pause_Service.hpp       1 Jul 2007 10:53:51 -0000       1.2
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,61 +0,0 @@
-// 
-// Copyright (C) 2007 Free Software Foundation, Inc.
-//
-// This file is part of GNU Cygnal.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-
-/// \file Pause_Service.hpp
-///    \brief The Pause service suspends itself (and its thread) for a number 
of milliseconds 
-///            if the scheduling queue has no high-priority items.
-
-#pragma once
-#ifndef __Pause_Service_hpp__
-#define __Pause_Service_hpp__
-
-#include "ACT.hpp"
-#include "Scheduler.hpp"
-
-namespace ACT {
-       //-------------------------
-       /**     \class Pause_Service
-        */
-       class Pause_Service
-               : public simple_act
-       {
-               /// Configuration parameter.
-               ///
-               /// Should eventually transition to a template parameter.
-               static const unsigned int ms_to_pause = 20 ;
-
-               /// Action body.
-               act_state run() ;
-
-               /// Scheduler determines whether pause is necessary or not.
-               Basic_Scheduler * the_scheduler ;
-
-       public:
-               /// 
-               Pause_Service( Basic_Scheduler * sc )
-                       : the_scheduler( sc )
-               {}
-
-       } ;
-
-       //-------------------------
-} // end namespace ACT
-
-#endif
\ No newline at end of file




reply via email to

[Prev in Thread] Current Thread [Next in Thread]