X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcfsm.h;h=3b1a0d4bed8cf8e0fd006d21403d7e80b7fb4e9a;hp=8822b2dd79e549015e1670c74c003ce968845132;hb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;hpb=f26bc2c10902a81955fe4b951c5679b42725eb00 diff --git a/lib/silcutil/silcfsm.h b/lib/silcutil/silcfsm.h index 8822b2dd..3b1a0d4b 100644 --- a/lib/silcutil/silcfsm.h +++ b/lib/silcutil/silcfsm.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - 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 @@ -23,18 +23,21 @@ * * 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 and sets silc_errno. * * 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 and sets silc_errno. * * 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"