X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcfsm_i.h;h=50475da5ca7c4d5204b2539eecaea5a8c68762d9;hb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;hp=455d8b9975d5b2ffe9558d593bfadc863669fbbd;hpb=c27a4ecc3e616e8a5ee09b8ca888ed6ff3e501f7;p=silc.git diff --git a/lib/silcutil/silcfsm_i.h b/lib/silcutil/silcfsm_i.h index 455d8b99..50475da5 100644 --- a/lib/silcutil/silcfsm_i.h +++ b/lib/silcutil/silcfsm_i.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2005 Pekka Riikonen + Copyright (C) 2005 - 2006 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 @@ -24,13 +24,24 @@ #error "Do not include this header directly" #endif -/* Semaphore structure, holds list of FSM machines that are waiting - for this semaphore. The SilcFSM has *next; pointer that is used - with SilcList. */ -struct SilcFSMSemaObject { +/* FSM state status */ +typedef enum { + SILC_FSM_ST_CONTINUE, /* Continue immediately to next state */ + SILC_FSM_ST_YIELD, /* Continue to next state through scheduler */ + SILC_FSM_ST_WAIT, /* Wait for some async call or timeout */ + SILC_FSM_ST_FINISH, /* Finish state machine and call destructor + through scheduler */ +} SilcFSMStatus; + +/* Event structure, holds list of FSM machines that are waiting for this + event. The SilcFSM has *next; pointer that is used with SilcList. + Internally events act as semaphore counters. */ +struct SilcFSMEventObject { SilcFSM fsm; /* Machine */ SilcList waiters; /* List of SilcFSM pointers */ - SilcUInt32 value; /* Current semaphore value */ + unsigned int value : 21; /* Current event semaphore value */ + unsigned int refcnt : 10; /* Reference counter */ + unsigned int allocated : 1; /* Set if allocated */ }; /* FSM and FSM thread context */ @@ -38,31 +49,40 @@ struct SilcFSMObject { struct SilcFSMObject *next; void *fsm_context; /* Caller's context */ SilcSchedule schedule; /* Scheduler */ - SilcFSMSema sema; /* Valid if waiting sema timeout */ + SilcFSMEvent event; /* Valid if waiting event timeout */ SilcFSMStateCallback next_state; /* Next state in machine */ + void *state_context; /* Extra state specific context */ SilcFSMDestructor destructor; /* Destructor */ void *destructor_context; union { /* Machine */ struct { - SilcUInt32 threads; /* Number of threads */ + SilcAtomic32 threads; /* Number of threads */ SilcMutex lock; /* Lock, valid if using real threads */ } m; /* Thread */ struct { struct SilcFSMObject *fsm; /* Machine */ - SilcFSMSema sema; /* Semaphore for waiting termination */ + SilcFSMEvent event; /* Event for waiting termination */ } t; } u; unsigned int thread : 1; /* Set if this is thread */ unsigned int real_thread : 1; /* Set if to use real threads */ unsigned int async_call : 1; /* Set if called real async call */ unsigned int finished : 1; /* Set if SILC_FSM_FINISH returned */ - unsigned int sema_timedout : 1; /* Set if waiting sema timedout */ + unsigned int event_timedout : 1; /* Set if waiting event timedout */ unsigned int synchronous : 1; /* Set if silc_fsm_start_sync called */ + unsigned int next_later : 1; /* Set if silc_fsm_next_later called */ + unsigned int started : 1; /* Set when started and not finished */ }; +/* Event signal context */ +typedef struct { + SilcFSMEvent event; /* Event */ + SilcFSM fsm; /* Signalled FSM */ +} *SilcFSMEventSignal; + /* Used internally by the SILC_FSM_CALL macros to detect whether async call is really async or not. */ static inline @@ -73,17 +93,14 @@ SilcBool silc_fsm_set_call(struct SilcFSMObject *fsm, SilcBool async_call) return old; } -/* Continues after callback */ -void silc_fsm_continue(void *fsm); -void silc_fsm_continue_sync(void *fsm); - /* Wait for thread to terminate */ SilcBool silc_fsm_thread_wait(void *fsm, void *thread); -/* Semaphores */ -SilcUInt32 silc_fsm_sema_wait(SilcFSMSema sema, void *fsm); -SilcUInt32 silc_fsm_sema_timedwait(SilcFSMSema sema, void *fsm, - SilcUInt32 seconds, SilcUInt32 useconds); -void silc_fsm_sema_post(SilcFSMSema sema); +/* Events */ +SilcUInt32 silc_fsm_event_wait(SilcFSMEvent event, void *fsm); +SilcUInt32 silc_fsm_event_timedwait(SilcFSMEvent event, void *fsm, + SilcUInt32 seconds, SilcUInt32 useconds, + SilcBool *ret_to); +void silc_fsm_event_signal(SilcFSMEvent event); #endif /* SILCFSM_I_H */