Added asynchronous event tasks to SILC Scheduler. Added
[crypto.git] / lib / silcutil / silcfsm.h
index 8822b2dd79e549015e1670c74c003ce968845132..503b8f43eafebff4ad8f81992582c095dca56e66 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2005, 2006 Pekka Riikonen
+  Copyright (C) 2005, 2006, 2007 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
  *
  * SILC FSM Interface implements a finite state machine.  The FSM can be
  * used to implement all kinds of machines and protocols.  The FSM supports
- * also threads and can be synchronized by using FSM semaphores.  The FSM
+ * also threads and can be synchronized by using mutex locks.  The FSM
  * also supports real system threads.  It is possible to create new FSM
  * thread and then execute in real system thread, if platform supports
  * threads.
  *
- * The FSM provides semaphores because of their versatility.  The FSM
- * semaphores can be used as a conditional variables and signallers, and
- * also as a mutual exclusion locks to protect critical sections.  The FSM
- * semaphores can safely be used to synchronize also FSM threads that are
- * executed in real system threads.  This makes SILC FSM very effective
- * tool to implement complex machines whether they are executed in single
- * thread or in multiple threads.
+ * The FSM provides also asynchronous events that can be used to wait for
+ * some events or states to occur.  The FSM events may be used as condition
+ * variables and signallers.  The FSM events can safely be used in FSM
+ * threads that are executed in real system threads.
+ *
+ * To synchronize machines that use FSM threads that are executed in real
+ * system threads the SILC Mutex API (silcmutex.h) may be used.  Normal
+ * multi-threaded coding conventions apply when programming with real FSM
+ * threads.  If the FSM threads are not real system threads, synchronization
+ * is not required.
  *
  ***/
 
@@ -91,7 +94,7 @@ typedef struct SilcFSMObject SilcFSMStruct;
  ***/
 typedef struct SilcFSMObject *SilcFSMThread;
 
-/****s* silcutil/SilcFSMAPI/SilcFSM
+/****s* silcutil/SilcFSMAPI/SilcFSMThreadStruct
  *
  * NAME
  *
@@ -106,25 +109,82 @@ typedef struct SilcFSMObject *SilcFSMThread;
  ***/
 typedef struct SilcFSMObject SilcFSMThreadStruct;
 
-/****d* silcutil/SilcFSMAPI/SilcFSMStatus
+/****d* silcutil/SilcFSMAPI/SILC_FSM_CONTINUE
  *
  * NAME
  *
- *    typedef enum { ... } SilcFSMStatus;
+ *    #define SILC_FSM_CONTINUE ...
  *
  * DESCRIPTION
  *
- *    Status values that the FSM state functions return.
+ *    Moves to next state synchronously.  This type is returned from state
+ *    functions to immediately move to next state.
  *
- * SOURCE
- */
-typedef enum {
-  SILC_FSM_CONTINUE,        /* Continue immediately to next state. */
-  SILC_FSM_WAIT,            /* Wait for some async call or timeout */
-  SILC_FSM_FINISH,          /* Finish state machine and call destructor
-                               through scheduler */
-} SilcFSMStatus;
-/***/
+ * EXAMPLE
+ *
+ *    SILC_FSM_STATE(silc_foo_state)
+ *    {
+ *      ...
+ *
+ *      // Move to next state now
+ *      silc_fsm_next(fsm, silc_foo_next_state);
+ *      return SILC_FSM_CONTINUE;
+ *    }
+ *
+ ***/
+#if defined(SILC_DEBUG)
+#define SILC_FSM_CONTINUE \
+  fsm->next_state(fsm, fsm->fsm_context, fsm->state_context);
+#else
+#define SILC_FSM_CONTINUE SILC_FSM_ST_CONTINUE;
+#endif /* SILC_DEBUG */
+
+/****d* silcutil/SilcFSMAPI/SILC_FSM_YIELD
+ *
+ * NAME
+ *
+ *    #define SILC_FSM_YIELD ...
+ *
+ * DESCRIPTION
+ *
+ *    Moves to next state through the machine scheduler.  Other threads
+ *    running in the machine will get running time with SILC_FSM_YIELD.
+ *    When using real threads, using SILC_FSM_YIELD is usually unnecessary.
+ *    This type is returned in the state function.
+ *
+ ***/
+#define SILC_FSM_YIELD SILC_FSM_ST_YIELD;
+
+/****d* silcutil/SilcFSMAPI/SILC_FSM_WAIT
+ *
+ * NAME
+ *
+ *    #define SILC_FSM_WAIT ...
+ *
+ * DESCRIPTION
+ *
+ *    Suspends the machine or thread until it is awaken.  This is used
+ *    when asynchronous call is made or timer is set, or something else
+ *    that requires waiting.  This type is returned in the state function.
+ *
+ ***/
+#define SILC_FSM_WAIT SILC_FSM_ST_WAIT
+
+/****d* silcutil/SilcFSMAPI/SILC_FSM_FINISH
+ *
+ * NAME
+ *
+ *    #define SILC_FSM_FINISH ...
+ *
+ * DESCRIPTION
+ *
+ *    Finishes the machine or thread and calls its destructor, if defined.
+ *    If the machine is finished when it has running threads the machine
+ *    will fatally fail.  User must always finish the threads before
+ *    finishing the machine.  This type is returned in the state function.
+ *
+ ***/
+#define SILC_FSM_FINISH SILC_FSM_ST_FINISH
 
 /****f* silcutil/SilcFSMAPI/SilcFSMDestructor
  *
@@ -139,8 +199,8 @@ typedef enum {
  *    silc_fsm_init function.  It will be called when a state function
  *    returns SILC_FSM_FINISH.  This function will be called through
  *    the scheduler; it will not be called immediately after the state
- *    function returns SILC_FSM_FINISH, but will be called later.
- *    The `fsm' may be freed or uninitialized in this function.
+ *    function returns SILC_FSM_FINISH, but will be called later.  The
+ *    `fsm' can be freed in this function.
  *
  ***/
 typedef void (*SilcFSMDestructor)(SilcFSM fsm, void *fsm_context,
@@ -158,10 +218,10 @@ typedef void (*SilcFSMDestructor)(SilcFSM fsm, void *fsm_context,
  *
  *    The destructor callback that was set in silc_fsm_thread_alloc or in
  *    silc_fsm_thread_init function.  It will be called when a state function
- *    returns SILC_FSM_FINISH.  This function will be called through
- *    the scheduler; it will not be called immediately after the state
- *    function returns SILC_FSM_FINISH, but will be called later.  The
- *    `thread' may be freed or uninitialized in this function.
+ *    returns SILC_FSM_FINISH.  This function will be called through the
+ *    scheduler; it will not be called immediately after the state function
+ *    returns SILC_FSM_FINISH, but will be called later.  The `thread' can
+ *    be freed in this function.
  *
  * NOTES
  *
@@ -182,7 +242,7 @@ typedef void (*SilcFSMThreadDestructor)(SilcFSMThread thread,
  *
  * DESCRIPTION
  *
- *    This macro is used to declare a FSM state function.  The `fsm' is
+ *    This macro is used to declare an FSM state function.  The `fsm' is
  *    the SilcFSM or SilcFSMThread context, the `fsm_context' is the context
  *    given as argument to silc_fsm_alloc, silc_fsm_init, silc_fsm_thread_init,
  *    or silc_fsm_thread_alloc function.  The `state_context' is the optional
@@ -191,14 +251,13 @@ typedef void (*SilcFSMThreadDestructor)(SilcFSMThread thread,
  * SOURCE
  */
 #define SILC_FSM_STATE(name)                                           \
-SilcFSMStatus name(struct SilcFSMObject *fsm, void *fsm_context,       \
-                  void *state_context)
+int name(struct SilcFSMObject *fsm, void *fsm_context, void *state_context)
 /***/
 
 /* State function callback */
-typedef SilcFSMStatus (*SilcFSMStateCallback)(struct SilcFSMObject *fsm,
-                                             void *fsm_context,
-                                             void *state_context);
+typedef int (*SilcFSMStateCallback)(struct SilcFSMObject *fsm,
+                                   void *fsm_context,
+                                   void *state_context);
 
 /****d* silcutil/SilcFSMAPI/SILC_FSM_CALL
  *
@@ -232,7 +291,7 @@ typedef SilcFSMStatus (*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;                  \
@@ -305,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
  *
@@ -313,12 +373,12 @@ do {                                              \
  *
  *    This macro is the only way to safely make sure that the thread has
  *    terminated by the time FSM continues from the waiting state.  Using
- *    semaphores to signal from the thread before SILC_FSM_FINISH is returned
+ *    FSM events to signal from the thread before SILC_FSM_FINISH is returned
  *    works with normal FSM threads, but especially with real system threads
  *    it does not guarantee that the FSM won't continue before the thread has
  *    actually terminated.  Usually this is not a problem, but it can be a
- *    problem if the FSM is waiting to be freed or uninitialized.  In this
- *    case using this macro is strongly recommended.
+ *    problem if the FSM is waiting to be freed.  In this case using this
+ *    macro is strongly recommended.
  *
  ***/
 #define SILC_FSM_THREAD_WAIT(thread)           \
@@ -343,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.
  *
  * EXAMPLE
  *
@@ -388,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
  *
@@ -421,33 +486,25 @@ 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.
  *
  * NOTES
  *
- *    Note the limitations on using `real_thread' boolean to indicate running
- *    the FSM thread in a real system thread:
- *
  *    If the system does not support threads, then this function will revert
  *    back to normal FSM threads.
  *
  *    If the `real_thread' is TRUE then FSM will allocate new SilcSchedule
- *    for the FSM thread.  This is done because the SilcSchedule that the
- *    `fsm' use cannot be used in the thread.  This is limitation in the
- *    SilcSchedule implementation.  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.
- *
- *    You may still however use the original SilcSchedule if you wish.  In
- *    this case note its limitation: you may only add and/or remove tasks,
- *    tasks cannot be executed in the thread.  You will need to deliver the
- *    original SilcSchedule to the thread in the `thread_context' if you wish
- *    to use it.
- *
- *    If `real_thread' is FALSE then no limitations on what can be run in
- *    the thread exist.  In this case silc_fsm_get_schedule will return
+ *    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.  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
  *    silc_fsm_init.
  *
@@ -491,8 +548,7 @@ SilcFSMThread silc_fsm_thread_alloc(SilcFSM fsm,
  *    Initializes a pre-allocated SilcFSMThread context.  This call is
  *    equivalent to silc_fsm_thread_alloc except that this takes the
  *    pre-allocated 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.  If the `real_thread' is TRUE then the
+ *    called if this was called.  If the `real_thread' is TRUE then the
  *    thread will actually be executed in real thread, if platform supports
  *    them.
  *
@@ -589,9 +645,11 @@ void silc_fsm_start_sync(void *fsm, SilcFSMStateCallback start_state);
  *
  *    Set the next state to be executed.  If the state function that
  *    call this function returns SILC_FSM_CONTINUE, the `next_state'
- *    will be executed immediately.  This function must always be used
- *    to set the next state in the machine or thread.  This function is
- *    used with both SilcFSM and SilcFSMThread contexts.
+ *    will be executed immediately.  If it returns SILC_FSM_YIELD it
+ *    yields the thread and the `next_state' will be run after other
+ *    threads have run first.  This function must always be used to set
+ *    the next state in the machine or thread.  This function is used
+ *    with both SilcFSM and SilcFSMThread contexts.
  *
  * EXAMPLE
  *
@@ -623,6 +681,10 @@ void silc_fsm_next(void *fsm, SilcFSMStateCallback next_state);
  *    If both `seconds' and `useconds' are 0, the effect is same as calling
  *    silc_fsm_next function, and SILC_FSM_CONTINUE must be returned.
  *
+ *    If silc_fsm_continue or silc_fsm_continue_sync is called while the
+ *    machine or thread is in SILC_FSM_WAIT state the timeout is automatically
+ *    canceled and the state moves to the next state.
+ *
  * EXAMPLE
  *
  *    // Move to next state after 10 seconds
@@ -669,6 +731,27 @@ void silc_fsm_continue(void *fsm);
  ***/
 void silc_fsm_continue_sync(void *fsm);
 
+/****f* silcutil/SilcFSMAPI/silc_fsm_finish
+ *
+ * SYNOPSIS
+ *
+ *    void silc_fsm_finish(void *fsm);
+ *
+ * DESCRIPTION
+ *
+ *    Finishes the `fsm'.  This function may be used in case the FSM
+ *    needs to be finished outside FSM states.  Usually FSM is finished
+ *    by returning SILC_FSM_FINISH from the state, but if this is not
+ *    possible this function may be called.  This function is used with
+ *    both SilcFSM and SilcFSMThread contexts.
+ *
+ *    If the `fsm' is a machine and it has running threads, the machine
+ *    will fatally fail.  The caller must first finish the threads and
+ *    then the machine.
+ *
+ ***/
+void silc_fsm_finish(void *fsm);
+
 /****f* silcutil/SilcFSMAPI/silc_fsm_set_context
  *
  * SYNOPSIS
@@ -770,111 +853,124 @@ SilcSchedule silc_fsm_get_schedule(void *fsm);
  ***/
 SilcFSM silc_fsm_get_machine(SilcFSMThread thread);
 
+/****f* silcutil/SilcFSMAPI/silc_fsm_is_started
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool silc_fsm_is_started(void *fsm);
+ *
+ * DESCRIPTION
+ *
+ *    Returns TRUE if the machine or thread `fsm' has been started and has
+ *    not been finished yet.  This function is used with both SilcFSM and
+ *    SilcFSMThread contexts.
+ *
+ ***/
+SilcBool silc_fsm_is_started(void *fsm);
 
-/* FSM Semaphores */
+/* FSM Events */
 
-/****s* silcutil/SilcFSMAPI/SilcFSMSema
+/****s* silcutil/SilcFSMAPI/SilcFSMEvent
  *
  * NAME
  *
- *    typedef struct SilcFSMSemaObject *SilcFSMSema;
+ *    typedef struct SilcFSMEventObject *SilcFSMEvent;
  *
  * DESCRIPTION
  *
- *    The FSM semaphore context allocated with silc_fsm_sema_alloc.  The
- *    caller must free it with silc_fsm_sema_free.  It is also possible
- *    to use pre-allocated SilcFSMSemaStruct instead of SilcFSMSema context.
+ *    The FSM event context allocated with silc_fsm_event_alloc.  The
+ *    caller must free it with silc_fsm_event_free.  It is also possible
+ *    to use pre-allocated SilcFSMEventStruct instead of SilcFSMEvent context.
  *
  ***/
-typedef struct SilcFSMSemaObject *SilcFSMSema;
+typedef struct SilcFSMEventObject *SilcFSMEvent;
 
-/****s* silcutil/SilcFSMAPI/SilcFSMSemaStruct
+/****s* silcutil/SilcFSMAPI/SilcFSMEventStruct
  *
  * NAME
  *
- *    typedef struct SilcFSMSemaObject SilcFSMSemaStruct;
+ *    typedef struct SilcFSMEventObject SilcFSMEventStruct;
  *
  * DESCRIPTION
  *
- *    The FSM semaphore context that can be used as pre-allocated context.
- *    It is initialized with silc_fsm_sema_init.  It need not be
+ *    The FSM event context that can be used as pre-allocated context.
+ *    It is initialized with silc_fsm_event_init.  It need not be
  *    uninitialized.
  *
  ***/
-typedef struct SilcFSMSemaObject SilcFSMSemaStruct;
+typedef struct SilcFSMEventObject SilcFSMEventStruct;
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_sema_alloc
+/****f* silcutil/SilcFSMAPI/silc_fsm_event_alloc
  *
  * SYNOPSIS
  *
- *    SilcFSMSema silc_fsm_sema_alloc(SilcFSM fsm, SilcUInt32 value);
+ *    SilcFSMEvent silc_fsm_event_alloc(SilcFSM fsm);
  *
  * DESCRIPTION
  *
- *    Allocates FSM semaphore with initial value of `value'.  Semaphores are
- *    counters for resources shared between machine and threads.  Semaphores
- *    can be waited until the semaphore value is non-zero.  The FSM will be
- *    suspended when waiting for semaphore.  When the semaphore is incremented
- *    all that are waiting for the semaphore will be signalled and awaken.
- *
- *    Semaphores can be used to wait for example when thread terminates, or
- *    when thread moves into a specific state, or to protect critical
- *    sections.  The FSM semaphores can be used also in FSM threads that are
- *    executed in real system threads.
+ *    Allocates asynchronous FSM event.  FSM events are asynchronous events
+ *    that can be waited and signalled.  They can be used as condition
+ *    variables and signallers.  They can be used for example to wait that
+ *    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.  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_SEMA_WAIT and SILC_FSM_SEMA_TIMEDWAIT to wait
- *    for semaphore.  Use the SILC_FSM_SEMA_POST macro to increment the
- *    counter and wake up all waiters.
+ *    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
+ *    waiters.
  *
  ***/
-SilcFSMSema silc_fsm_sema_alloc(SilcFSM fsm, SilcUInt32 value);
+SilcFSMEvent silc_fsm_event_alloc(SilcFSM fsm);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_sema_init
+/****f* silcutil/SilcFSMAPI/silc_fsm_event_init
  *
  * SYNOPSIS
  *
- *    void silc_fsm_sema_init(SilcFSMSema sema, SilcFSM fsm, SilcUInt32 value);
+ *    void silc_fsm_event_init(SilcFSMEvent event, SilcFSM fsm);
  *
  * DESCRIPTION
  *
- *    Initializes a pre-allocates semaphore context.  This call is
- *    equivalent to silc_fsm_sema_alloc except this use the pre-allocated
- *    context.  This fuction does not allocate any memory.
+ *    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.  The `fsm'
+ *    must be the machine, not a thread.
  *
  ***/
-void silc_fsm_sema_init(SilcFSMSema sema, SilcFSM fsm, SilcUInt32 value);
+void silc_fsm_event_init(SilcFSMEvent event, SilcFSM fsm);
 
-/****f* silcutil/SilcFSMAPI/silc_fsm_sema_free
+/****f* silcutil/SilcFSMAPI/silc_fsm_event_free
  *
  * SYNOPSIS
  *
- *    void silc_fsm_sema_free(SilcFSMSema sema);
+ *    void silc_fsm_event_free(SilcFSMEvent event);
  *
  * DESCRIPTION
  *
- *    Free the semaphore allocated by silc_fsm_sema_alloc function.
+ *    Free the event allocated by silc_fsm_event_alloc function.
  *
  ***/
-void silc_fsm_sema_free(SilcFSMSema sema);
+void silc_fsm_event_free(SilcFSMEvent event);
 
-/****d* silcutil/SilcFSMAPI/SILC_FSM_SEMA_WAIT
+/****d* silcutil/SilcFSMAPI/SILC_FSM_EVENT_WAIT
  *
  * NAME
  *
- *    SILC_FSM_SEMA_WAIT(semaphore)
+ *    SILC_FSM_EVENT_WAIT(event)
  *
  * DESCRIPTION
  *
- *    Macro used to wait for the `semaphore' to become non-zero.  The
- *    machine will be suspended while it is waiting for the semaphore.
+ *    Macro used to wait for the `event' to be signalled.  The machine
+ *    or thread will be suspended while it is waiting for the event.
  *    This macro can only be used in FSM state functions.  When the
- *    semaphore is signalled the FSM will re-enter the current state (or
+ *    event is signalled the FSM will re-enter the current state (or
  *    state that was set with silc_fsm_next before waiting).
  *
  * EXAMPLE
  *
  *    // Signalling example
- *    ctx->sema = silc_fsm_sema_alloc(fsm, 0);
+ *    ctx->async_event = silc_fsm_event_alloc(fsm);
  *    ...
  *
  *    SILC_FSM_STATE(silc_foo_state)
@@ -882,7 +978,7 @@ void silc_fsm_sema_free(SilcFSMSema sema);
  *      ...
  *
  *      // Wait here for async call to complete
- *      SILC_FSM_SEMA_WAIT(ctx->async_sema);
+ *      SILC_FSM_EVENT_WAIT(ctx->async_event);
  *
  *      // Async call completed
  *      if (ctx->async_success == FALSE)
@@ -890,41 +986,28 @@ void silc_fsm_sema_free(SilcFSMSema sema);
  *      ...
  *    }
  *
- *    // Mutual exclusion example
- *    ctx->lock = silc_fsm_sema_alloc(fsm, 1);
- *    ...
- *
- *    SILC_FSM_STATE(silc_foo_state)
- *    {
- *      ...
- *      SILC_FSM_SEMA_WAIT(ctx->lock);
- *      very critical stuff...
- *      SILC_FSM_SEMA_POST(ctx->lock);
- *      ...
- *    }
- *
  ***/
-#define SILC_FSM_SEMA_WAIT(sema)               \
+#define SILC_FSM_EVENT_WAIT(event)             \
 do {                                           \
-  if (silc_fsm_sema_wait(sema, fsm) == 0)      \
+  if (silc_fsm_event_wait(event, fsm) == 0)    \
     return SILC_FSM_WAIT;                      \
 } while(0)
 
-/****d* silcutil/SilcFSMAPI/SILC_FSM_SEMA_TIMEDWAIT
+/****d* silcutil/SilcFSMAPI/SILC_FSM_EVENT_TIMEDWAIT
  *
  * NAME
  *
- *    SILC_FSM_SEMA_TIMEDWAIT(semaphore, seconds, useconds, timedout)
+ *    SILC_FSM_EVENT_TIMEDWAIT(event, seconds, useconds, timedout)
  *
  * DESCRIPTION
  *
- *    Macro used to wait for the `semaphore' to become non-zero, or until
+ *    Macro used to wait for the `event' to be signalled, or until
  *    the timeout specified by `seconds' and `useconds' has elapsed.  If
- *    the timeout occurs before the semaphore becomes non-zero, the machine
+ *    the timeout occurs before the event is signalled, the machine
  *    will wakeup.  The `timedout' is SilcBool pointer and if it is
  *    non-NULL indication of whether timeout occurred or not is saved to
  *    the pointer.  This macro can only be used in FSM state functions.
- *    When the semaphore is signalled or timedout the FSM will re-enter
+ *    When the event is signalled or timedout the FSM will re-enter
  *    the current state (or state that was set with silc_fsm_next before
  *    waiting).
  *
@@ -935,9 +1018,8 @@ do {                                               \
  *      SilcBool timedout;
  *      ...
  *
- *
  *      // Wait here for async call to complete, or 10 seconds for timeout
- *      SILC_FSM_SEMA_TIMEDWAIT(ctx->async_sema, 10, 0, &timedout);
+ *      SILC_FSM_EVENT_TIMEDWAIT(ctx->async_event, 10, 0, &timedout);
  *
  *      // See if timeout occurred
  *      if (timedout == TRUE)
@@ -950,24 +1032,23 @@ do {                                             \
  *    }
  *
  ***/
-#define SILC_FSM_SEMA_TIMEDWAIT(sema, seconds, useconds, ret_to)         \
-do {                                                                     \
-  if (silc_fsm_sema_timedwait(sema, fsm, seconds, useconds, ret_to) == 0) \
-    return SILC_FSM_WAIT;                                                \
+#define SILC_FSM_EVENT_TIMEDWAIT(event, seconds, useconds, ret_to)     \
+do {                                                                   \
+  if (silc_fsm_event_timedwait(event, fsm, seconds, useconds, ret_to) == 0) \
+    return SILC_FSM_WAIT;                                              \
 } while(0)
 
-/****f* silcutil/SilcFSMAPI/SILC_FSM_SEMA_POST
+/****f* silcutil/SilcFSMAPI/SILC_FSM_EVENT_SIGNAL
  *
  * SYNOPSIS
  *
- *    SILC_FSM_SEMA_POST(semaphore)
+ *    SILC_FSM_EVENT_SIGNAL(event)
  *
  * DESCRIPTION
  *
- *    Increases the semaphore counter and awakens everybody that are
- *    waiting for this semaphore.  This macro never blocks.  It can be
- *    safely called at any place in state function and in asynchronous
- *    callbacks or other functions.
+ *    Signals the `event' and awakens everybody that are waiting for this
+ *    event.  This macro never blocks.  It can be safely called at any place
+ *    in state function and in asynchronous callbacks or other functions.
  *
  * EXAMPLE
  *
@@ -977,14 +1058,14 @@ do {                                                                       \
  *
  *      // Notify all waiters
  *      ctx->async_success = TRUE;
- *      SILC_FSM_SEMA_POST(ctx->async_sema);
+ *      SILC_FSM_EVENT_SIGNAL(ctx->async_event);
  *      ...
  *    }
  *
  ***/
-#define SILC_FSM_SEMA_POST(sema)               \
+#define SILC_FSM_EVENT_SIGNAL(event)           \
 do {                                           \
-  silc_fsm_sema_post(sema);                    \
+  silc_fsm_event_signal(event);                        \
 } while(0)
 
 #include "silcfsm_i.h"