SILC Runtime Toolkit 1.2 Beta 1
[runtime.git] / lib / silcutil / silcfsm.h
index 0eb53f4e77cc17f93bcb6c4f59759d0a881e82ba..0ac6b9bdab1779932a48eb9ac98354eba7e760a8 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2005, 2006, 2007 Pekka Riikonen
+  Copyright (C) 2005 - 2008 Pekka Riikonen
 
   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
@@ -17,7 +17,7 @@
 
 */
 
-/****h* silcutil/SILC Finite State Machine
+/****h* silcutil/Finite State Machine
  *
  * DESCRIPTION
  *
@@ -44,7 +44,7 @@
 #ifndef SILCFSM_H
 #define SILCFSM_H
 
-/****s* silcutil/SilcFSMAPI/SilcFSM
+/****s* silcutil/SilcFSM
  *
  * NAME
  *
@@ -60,7 +60,7 @@
  ***/
 typedef struct SilcFSMObject *SilcFSM;
 
-/****s* silcutil/SilcFSMAPI/SilcFSMStruct
+/****s* silcutil/SilcFSMStruct
  *
  * NAME
  *
@@ -75,7 +75,7 @@ typedef struct SilcFSMObject *SilcFSM;
  ***/
 typedef struct SilcFSMObject SilcFSMStruct;
 
-/****s* silcutil/SilcFSMAPI/SilcFSMThread
+/****s* silcutil/SilcFSMThread
  *
  * NAME
  *
@@ -94,7 +94,7 @@ typedef struct SilcFSMObject SilcFSMStruct;
  ***/
 typedef struct SilcFSMObject *SilcFSMThread;
 
-/****s* silcutil/SilcFSMAPI/SilcFSM
+/****s* silcutil/SilcFSMThreadStruct
  *
  * NAME
  *
@@ -109,7 +109,7 @@ typedef struct SilcFSMObject *SilcFSMThread;
  ***/
 typedef struct SilcFSMObject SilcFSMThreadStruct;
 
-/****d* silcutil/SilcFSMAPI/SILC_FSM_CONTINUE
+/****d* silcutil/SILC_FSM_CONTINUE
  *
  * NAME
  *
@@ -117,8 +117,8 @@ typedef struct SilcFSMObject SilcFSMThreadStruct;
  *
  * DESCRIPTION
  *
- *    Moves to next state synchronously.  This type is used is returned
- *    from state functions to immediately move to next state.
+ *    Moves to next state synchronously.  This type is returned from state
+ *    functions to immediately move to next state.
  *
  * EXAMPLE
  *
@@ -139,7 +139,7 @@ typedef struct SilcFSMObject SilcFSMThreadStruct;
 #define SILC_FSM_CONTINUE SILC_FSM_ST_CONTINUE;
 #endif /* SILC_DEBUG */
 
-/****d* silcutil/SilcFSMAPI/SILC_FSM_YIELD
+/****d* silcutil/SILC_FSM_YIELD
  *
  * NAME
  *
@@ -155,7 +155,7 @@ typedef struct SilcFSMObject SilcFSMThreadStruct;
  ***/
 #define SILC_FSM_YIELD SILC_FSM_ST_YIELD;
 
-/****d* silcutil/SilcFSMAPI/SILC_FSM_WAIT
+/****d* silcutil/SILC_FSM_WAIT
  *
  * NAME
  *
@@ -170,7 +170,7 @@ typedef struct SilcFSMObject SilcFSMThreadStruct;
  ***/
 #define SILC_FSM_WAIT SILC_FSM_ST_WAIT
 
-/****d* silcutil/SilcFSMAPI/SILC_FSM_FINISH
+/****d* silcutil/SILC_FSM_FINISH
  *
  * NAME
  *
@@ -186,7 +186,7 @@ typedef struct SilcFSMObject SilcFSMThreadStruct;
  ***/
 #define SILC_FSM_FINISH SILC_FSM_ST_FINISH
 
-/****f* silcutil/SilcFSMAPI/SilcFSMDestructor
+/****f* silcutil/SilcFSMDestructor
  *
  * SYNOPSIS
  *
@@ -206,7 +206,7 @@ typedef struct SilcFSMObject SilcFSMThreadStruct;
 typedef void (*SilcFSMDestructor)(SilcFSM fsm, void *fsm_context,
                                   void *destructor_context);
 
-/****f* silcutil/SilcFSMAPI/SilcFSMThreadDestructor
+/****f* silcutil/SilcFSMThreadDestructor
  *
  * SYNOPSIS
  *
@@ -234,7 +234,7 @@ typedef void (*SilcFSMThreadDestructor)(SilcFSMThread thread,
                                        void *thread_context,
                                        void *destructor_context);
 
-/****d* silcutil/SilcFSMAPI/SILC_FSM_STATE
+/****d* silcutil/SILC_FSM_STATE
  *
  * NAME
  *
@@ -259,7 +259,7 @@ typedef int (*SilcFSMStateCallback)(struct SilcFSMObject *fsm,
                                    void *fsm_context,
                                    void *state_context);
 
-/****d* silcutil/SilcFSMAPI/SILC_FSM_CALL
+/****d* silcutil/SILC_FSM_CALL
  *
  * NAME
  *
@@ -291,14 +291,14 @@ typedef int (*SilcFSMStateCallback)(struct SilcFSMObject *fsm,
  ***/
 #define SILC_FSM_CALL(function)                        \
 do {                                           \
-  assert(!silc_fsm_set_call(fsm, TRUE));       \
+  SILC_VERIFY(!silc_fsm_set_call(fsm, TRUE));  \
   function;                                    \
   if (!silc_fsm_set_call(fsm, FALSE))          \
     return SILC_FSM_CONTINUE;                  \
   return SILC_FSM_WAIT;                                \
 } while(0)
 
-/****d* silcutil/SilcFSMAPI/SILC_FSM_CALL_CONTINUE
+/****d* silcutil/SILC_FSM_CALL_CONTINUE
  *
  * NAME
  *
@@ -325,7 +325,7 @@ do {                                                \
     silc_fsm_continue(fsm);                    \
 } while(0)
 
-/****d* silcutil/SilcFSMAPI/SILC_FSM_CALL_CONTINUE_SYNC
+/****d* silcutil/SILC_FSM_CALL_CONTINUE_SYNC
  *
  * NAME
  *
@@ -354,7 +354,7 @@ do {                                                \
     silc_fsm_continue_sync(fsm);               \
 } while(0)
 
-/****d* silcutil/SilcFSMAPI/SILC_FSM_THREAD_WAIT
+/****d* silcutil/SILC_FSM_THREAD_WAIT
  *
  * NAME
  *
@@ -364,7 +364,8 @@ do {                                                \
  *
  *    Macro used to wait for the `thread' to terminate.  The machine or
  *    thread will be suspended while it is waiting for the thread to
- *    terminate.
+ *    terminate.  The machine or thread will continue once the waited
+ *    thread has terminated.
  *
  * NOTES
  *
@@ -386,7 +387,7 @@ do {                                                \
   return SILC_FSM_WAIT;                                \
 } while(0)
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_alloc
+/****f* silcutil/silc_fsm_alloc
  *
  * SYNOPSIS
  *
@@ -402,6 +403,9 @@ do {                                                \
  *    caller must free the returned context with silc_fsm_free.  The
  *    `fsm_context' is delivered to every FSM state function.  The `schedule'
  *    is the caller's scheduler and the FSM will be run in the scheduler.
+ *    If `schedule' is NULL this will call silc_schedule_get_global to try
+ *    get global scheduler.  Returns NULL on error or if system is out of
+ *    memory and sets silc_errno.
  *
  * EXAMPLE
  *
@@ -430,7 +434,7 @@ SilcFSM silc_fsm_alloc(void *fsm_context,
                        void *destructor_context,
                        SilcSchedule schedule);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_init
+/****f* silcutil/silc_fsm_init
  *
  * SYNOPSIS
  *
@@ -447,7 +451,9 @@ SilcFSM silc_fsm_alloc(void *fsm_context,
  *    as argument.  The silc_fsm_free must not be called if this was called.
  *    Returns TRUE if the initialization is Ok or FALSE if error occurred.
  *    This function does not allocate any memory.  The `schedule' is the
- *    caller's scheduler and the FSM will be run in the scheduler.
+ *    caller's scheduler and the FSM will be run in the scheduler.  If
+ *    `schedule' is NULL this will call silc_schedule_get_global to try to
+ *    get global scheduler.
  *
  * EXAMPLE
  *
@@ -463,7 +469,7 @@ SilcBool silc_fsm_init(SilcFSM fsm,
                        void *destructor_context,
                        SilcSchedule schedule);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_thread_alloc
+/****f* silcutil/silc_fsm_thread_alloc
  *
  * SYNOPSIS
  *
@@ -480,7 +486,8 @@ SilcBool silc_fsm_init(SilcFSM fsm,
  *    thread context with silc_fsm_free.  If the 'real_thread' is TRUE
  *    then the thread will actually be executed in real thread, if platform
  *    supports them.  The `thread_context' is delivered to every state
- *    function in the thread.
+ *    function in the thread.  Returns NULL on error or if the system is out
+ *    of memory and sets silc_errno.
  *
  * NOTES
  *
@@ -491,8 +498,11 @@ SilcBool silc_fsm_init(SilcFSM fsm,
  *    for the FSM thread. If you need scheduler in the real thread it is
  *    strongly recommended that you use the SilcSchedule that is allocated
  *    for the thread.  You can retrieve the SilcSchedule from the thread
- *    using silc_fsm_get_schedule function.  Note that, the allocated
- *    SilcSchedule will become invalid after the thread finishes.
+ *    using silc_fsm_get_schedule function.  The new scheduler is a child
+ *    scheduler of the original scheduler used with `fsm'.  Note that, the
+ *    allocated SilcSchedule will become invalid after the thread finishes.
+ *    Note also that the scheduler is automatically set as global scheduler
+ *    in that thread by calling silc_schedule_set_global.
  *
  *    If `real_thread' is FALSE the silc_fsm_get_schedule will return
  *    the SilcSchedule that was originally given to silc_fsm_alloc or
@@ -522,7 +532,7 @@ SilcFSMThread silc_fsm_thread_alloc(SilcFSM fsm,
                                    void *destructor_context,
                                    SilcBool real_thread);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_thread_init
+/****f* silcutil/silc_fsm_thread_init
  *
  * SYNOPSIS
  *
@@ -561,7 +571,7 @@ void silc_fsm_thread_init(SilcFSMThread thread,
                          void *destructor_context,
                          SilcBool real_thread);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_free
+/****f* silcutil/silc_fsm_free
  *
  * SYNOPSIS
  *
@@ -581,7 +591,7 @@ void silc_fsm_thread_init(SilcFSMThread thread,
  ***/
 void silc_fsm_free(void *fsm);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_start
+/****f* silcutil/silc_fsm_start
  *
  * SYNOPSIS
  *
@@ -605,7 +615,7 @@ void silc_fsm_free(void *fsm);
  ***/
 void silc_fsm_start(void *fsm, SilcFSMStateCallback start_state);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_start_sync
+/****f* silcutil/silc_fsm_start_sync
  *
  * SYNOPSIS
  *
@@ -625,7 +635,7 @@ void silc_fsm_start(void *fsm, SilcFSMStateCallback start_state);
  ***/
 void silc_fsm_start_sync(void *fsm, SilcFSMStateCallback start_state);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_next
+/****f* silcutil/silc_fsm_next
  *
  * SYNOPSIS
  *
@@ -650,7 +660,7 @@ void silc_fsm_start_sync(void *fsm, SilcFSMStateCallback start_state);
  ***/
 void silc_fsm_next(void *fsm, SilcFSMStateCallback next_state);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_next_later
+/****f* silcutil/silc_fsm_next_later
  *
  * SYNOPSIS
  *
@@ -685,7 +695,7 @@ void silc_fsm_next(void *fsm, SilcFSMStateCallback next_state);
 void silc_fsm_next_later(void *fsm, SilcFSMStateCallback next_state,
                         SilcUInt32 seconds, SilcUInt32 useconds);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_continue
+/****f* silcutil/silc_fsm_continue
  *
  * SYNOPSIS
  *
@@ -703,7 +713,7 @@ void silc_fsm_next_later(void *fsm, SilcFSMStateCallback next_state,
  ***/
 void silc_fsm_continue(void *fsm);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_continue_sync
+/****f* silcutil/silc_fsm_continue_sync
  *
  * SYNOPSIS
  *
@@ -721,7 +731,7 @@ void silc_fsm_continue(void *fsm);
  ***/
 void silc_fsm_continue_sync(void *fsm);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_finish
+/****f* silcutil/silc_fsm_finish
  *
  * SYNOPSIS
  *
@@ -742,7 +752,7 @@ void silc_fsm_continue_sync(void *fsm);
  ***/
 void silc_fsm_finish(void *fsm);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_set_context
+/****f* silcutil/silc_fsm_set_context
  *
  * SYNOPSIS
  *
@@ -758,7 +768,7 @@ void silc_fsm_finish(void *fsm);
  ***/
 void silc_fsm_set_context(void *fsm, void *fsm_context);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_get_context
+/****f* silcutil/silc_fsm_get_context
  *
  * SYNOPSIS
  *
@@ -774,7 +784,7 @@ void silc_fsm_set_context(void *fsm, void *fsm_context);
  ***/
 void *silc_fsm_get_context(void *fsm);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_set_state_context
+/****f* silcutil/silc_fsm_set_state_context
  *
  * SYNOPSIS
  *
@@ -790,7 +800,7 @@ void *silc_fsm_get_context(void *fsm);
  ***/
 void silc_fsm_set_state_context(void *fsm, void *state_context);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_get_state_context
+/****f* silcutil/silc_fsm_get_state_context
  *
  * SYNOPSIS
  *
@@ -805,7 +815,7 @@ void silc_fsm_set_state_context(void *fsm, void *state_context);
  ***/
 void *silc_fsm_get_state_context(void *fsm);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_get_schedule
+/****f* silcutil/silc_fsm_get_schedule
  *
  * SYNOPSIS
  *
@@ -830,7 +840,7 @@ void *silc_fsm_get_state_context(void *fsm);
  ***/
 SilcSchedule silc_fsm_get_schedule(void *fsm);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_get_machine
+/****f* silcutil/silc_fsm_get_machine
  *
  * SYNOPSIS
  *
@@ -843,7 +853,7 @@ SilcSchedule silc_fsm_get_schedule(void *fsm);
  ***/
 SilcFSM silc_fsm_get_machine(SilcFSMThread thread);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_is_started
+/****f* silcutil/silc_fsm_is_started
  *
  * SYNOPSIS
  *
@@ -860,7 +870,7 @@ SilcBool silc_fsm_is_started(void *fsm);
 
 /* FSM Events */
 
-/****s* silcutil/SilcFSMAPI/SilcFSMEvent
+/****s* silcutil/SilcFSMEvent
  *
  * NAME
  *
@@ -875,7 +885,7 @@ SilcBool silc_fsm_is_started(void *fsm);
  ***/
 typedef struct SilcFSMEventObject *SilcFSMEvent;
 
-/****s* silcutil/SilcFSMAPI/SilcFSMEventStruct
+/****s* silcutil/SilcFSMEventStruct
  *
  * NAME
  *
@@ -890,7 +900,7 @@ typedef struct SilcFSMEventObject *SilcFSMEvent;
  ***/
 typedef struct SilcFSMEventObject SilcFSMEventStruct;
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_event_alloc
+/****f* silcutil/silc_fsm_event_alloc
  *
  * SYNOPSIS
  *
@@ -904,7 +914,8 @@ typedef struct SilcFSMEventObject SilcFSMEventStruct;
  *    some event happens, some thread moves to a specific state or similar.
  *    The FSM Events may also be used in FSM threads that are executed in
  *    real system threads.  It is safe to wait and signal the event from
- *    threads.
+ *    threads.  The `fsm' must be the machine, not a thread.  Returns NULL
+ *    if system is out of memory or `fsm' is not FSM machine.
  *
  *    Use the macros SILC_FSM_EVENT_WAIT and SILC_FSM_EVENT_TIMEDWAIT to wait
  *    for the event.  Use the SILC_FSM_EVENT_SIGNAL macro to signal all the
@@ -913,7 +924,7 @@ typedef struct SilcFSMEventObject SilcFSMEventStruct;
  ***/
 SilcFSMEvent silc_fsm_event_alloc(SilcFSM fsm);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_event_init
+/****f* silcutil/silc_fsm_event_init
  *
  * SYNOPSIS
  *
@@ -923,12 +934,13 @@ SilcFSMEvent silc_fsm_event_alloc(SilcFSM fsm);
  *
  *    Initializes a pre-allocates FSM event context.  This call is
  *    equivalent to silc_fsm_event_alloc except this use the pre-allocated
- *    context.  This fuction does not allocate any memory.
+ *    context.  This fuction does not allocate any memory.  The `fsm'
+ *    must be the machine, not a thread.
  *
  ***/
 void silc_fsm_event_init(SilcFSMEvent event, SilcFSM fsm);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_event_free
+/****f* silcutil/silc_fsm_event_free
  *
  * SYNOPSIS
  *
@@ -941,7 +953,7 @@ void silc_fsm_event_init(SilcFSMEvent event, SilcFSM fsm);
  ***/
 void silc_fsm_event_free(SilcFSMEvent event);
 
-/****d* silcutil/SilcFSMAPI/SILC_FSM_EVENT_WAIT
+/****d* silcutil/SILC_FSM_EVENT_WAIT
  *
  * NAME
  *
@@ -981,7 +993,7 @@ do {                                                \
     return SILC_FSM_WAIT;                      \
 } while(0)
 
-/****d* silcutil/SilcFSMAPI/SILC_FSM_EVENT_TIMEDWAIT
+/****d* silcutil/SILC_FSM_EVENT_TIMEDWAIT
  *
  * NAME
  *
@@ -1026,7 +1038,7 @@ do {                                                                      \
     return SILC_FSM_WAIT;                                              \
 } while(0)
 
-/****f* silcutil/SilcFSMAPI/SILC_FSM_EVENT_SIGNAL
+/****f* silcutil/SILC_FSM_EVENT_SIGNAL
  *
  * SYNOPSIS
  *