5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2005 - 2006 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
24 #error "Do not include this header directly"
27 /* FSM state status */
29 SILC_FSM_ST_CONTINUE, /* Continue immediately to next state */
30 SILC_FSM_ST_YIELD, /* Continue to next state through scheduler */
31 SILC_FSM_ST_WAIT, /* Wait for some async call or timeout */
32 SILC_FSM_ST_FINISH, /* Finish state machine and call destructor
36 /* Event structure, holds list of FSM machines that are waiting for this
37 event. The SilcFSM has *next; pointer that is used with SilcList.
38 Internally events act as semaphore counters. */
39 struct SilcFSMEventObject {
40 SilcFSM fsm; /* Machine */
41 SilcList waiters; /* List of SilcFSM pointers */
42 unsigned int value : 21; /* Current event semaphore value */
43 unsigned int refcnt : 10; /* Reference counter */
44 unsigned int allocated : 1; /* Set if allocated */
47 /* FSM and FSM thread context */
48 struct SilcFSMObject {
49 struct SilcFSMObject *next;
50 void *fsm_context; /* Caller's context */
51 SilcSchedule schedule; /* Scheduler */
52 SilcFSMEvent event; /* Valid if waiting event timeout */
53 SilcFSMStateCallback next_state; /* Next state in machine */
54 void *state_context; /* Extra state specific context */
55 SilcFSMDestructor destructor; /* Destructor */
56 void *destructor_context;
60 SilcAtomic32 threads; /* Number of threads */
61 SilcMutex lock; /* Lock, valid if using real threads */
66 struct SilcFSMObject *fsm; /* Machine */
67 SilcFSMEvent event; /* Event for waiting termination */
70 unsigned int thread : 1; /* Set if this is thread */
71 unsigned int real_thread : 1; /* Set if to use real threads */
72 unsigned int async_call : 1; /* Set if called real async call */
73 unsigned int finished : 1; /* Set if SILC_FSM_FINISH returned */
74 unsigned int event_timedout : 1; /* Set if waiting event timedout */
75 unsigned int synchronous : 1; /* Set if silc_fsm_start_sync called */
76 unsigned int next_later : 1; /* Set if silc_fsm_next_later called */
77 unsigned int started : 1; /* Set when started and not finished */
80 /* Event signal context */
82 SilcFSMEvent event; /* Event */
83 SilcFSM fsm; /* Signalled FSM */
84 } *SilcFSMEventSignal;
86 /* Used internally by the SILC_FSM_CALL macros to detect whether async
87 call is really async or not. */
89 SilcBool silc_fsm_set_call(struct SilcFSMObject *fsm, SilcBool async_call)
91 SilcBool old = fsm->async_call;
92 fsm->async_call = async_call;
96 /* Wait for thread to terminate */
97 SilcBool silc_fsm_thread_wait(void *fsm, void *thread);
100 SilcUInt32 silc_fsm_event_wait(SilcFSMEvent event, void *fsm);
101 SilcUInt32 silc_fsm_event_timedwait(SilcFSMEvent event, void *fsm,
102 SilcUInt32 seconds, SilcUInt32 useconds,
104 void silc_fsm_event_signal(SilcFSMEvent event);
106 #endif /* SILCFSM_I_H */