Added SILC Thread Queue API
[silc.git] / lib / silcutil / silcfsm_i.h
1 /*
2
3   silcfsm_i.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2005 - 2006 Pekka Riikonen
8
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.
12
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.
17
18 */
19
20 #ifndef SILCFSM_I_H
21 #define SILCFSM_I_H
22
23 #ifndef SILCFSM_H
24 #error "Do not include this header directly"
25 #endif
26
27 /* FSM state status */
28 typedef enum {
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
33                                 through scheduler */
34 } SilcFSMStatus;
35
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 */
45 };
46
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;
57   union {
58     /* Machine */
59     struct {
60       SilcAtomic32 threads;             /* Number of threads */
61       SilcMutex lock;                   /* Lock, valid if using real threads */
62     } m;
63
64     /* Thread */
65     struct {
66       struct SilcFSMObject *fsm;        /* Machine */
67       SilcFSMEvent event;               /* Event for waiting termination */
68     } t;
69   } u;
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 */
78 };
79
80 /* Event signal context */
81 typedef struct {
82   SilcFSMEvent event;                   /* Event */
83   SilcFSM fsm;                          /* Signalled FSM */
84 } *SilcFSMEventSignal;
85
86 /* Used internally by the SILC_FSM_CALL macros to detect whether async
87    call is really async or not. */
88 static inline
89 SilcBool silc_fsm_set_call(struct SilcFSMObject *fsm, SilcBool async_call)
90 {
91   SilcBool old = fsm->async_call;
92   fsm->async_call = async_call;
93   return old;
94 }
95
96 /* Wait for thread to terminate */
97 SilcBool silc_fsm_thread_wait(void *fsm, void *thread);
98
99 /* Events */
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,
103                                     SilcBool *ret_to);
104 void silc_fsm_event_signal(SilcFSMEvent event);
105
106 #endif /* SILCFSM_I_H */