Added silc_fsm_is_started.
[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 /* Semaphore structure, holds list of FSM machines that are waiting
28    for this semaphore.  The SilcFSM has *next; pointer that is used
29    with SilcList. */
30 struct SilcFSMSemaObject {
31   SilcFSM fsm;                          /* Machine */
32   SilcList waiters;                     /* List of SilcFSM pointers */
33   unsigned int value     : 21;          /* Current semaphore value */
34   unsigned int refcnt    : 10;          /* Reference counter */
35   unsigned int allocated : 1;           /* Set if allocated */
36 };
37
38 /* FSM and FSM thread context */
39 struct SilcFSMObject {
40   struct SilcFSMObject *next;
41   void *fsm_context;                    /* Caller's context */
42   SilcSchedule schedule;                /* Scheduler */
43   SilcFSMSema sema;                     /* Valid if waiting sema timeout */
44   SilcFSMStateCallback next_state;      /* Next state in machine */
45   void *state_context;                  /* Extra state specific context */
46   SilcFSMDestructor destructor;         /* Destructor */
47   void *destructor_context;
48   union {
49     /* Machine */
50     struct {
51       SilcUInt32 threads;               /* Number of threads */
52       SilcMutex lock;                   /* Lock, valid if using real threads */
53     } m;
54
55     /* Thread */
56     struct {
57       struct SilcFSMObject *fsm;        /* Machine */
58       SilcFSMSema sema;                 /* Semaphore for waiting termination */
59     } t;
60   } u;
61   unsigned int thread           : 1;    /* Set if this is thread */
62   unsigned int real_thread      : 1;    /* Set if to use real threads */
63   unsigned int async_call       : 1;    /* Set if called real async call */
64   unsigned int finished         : 1;    /* Set if SILC_FSM_FINISH returned */
65   unsigned int sema_timedout    : 1;    /* Set if waiting sema timedout */
66   unsigned int synchronous      : 1;    /* Set if silc_fsm_start_sync called */
67   unsigned int next_later       : 1;    /* Set if silc_fsm_next_later called */
68   unsigned int started          : 1;    /* Set when started and not finished */
69 };
70
71 /* Semaphore post context */
72 typedef struct {
73   SilcFSMSema sema;                     /* Semaphore */
74   SilcFSM fsm;                          /* Signalled FSM */
75 } *SilcFSMSemaPost;
76
77 /* Used internally by the SILC_FSM_CALL macros to detect whether async
78    call is really async or not. */
79 static inline
80 SilcBool silc_fsm_set_call(struct SilcFSMObject *fsm, SilcBool async_call)
81 {
82   SilcBool old = fsm->async_call;
83   fsm->async_call = async_call;
84   return old;
85 }
86
87 /* Wait for thread to terminate */
88 SilcBool silc_fsm_thread_wait(void *fsm, void *thread);
89
90 /* Semaphores */
91 SilcUInt32 silc_fsm_sema_wait(SilcFSMSema sema, void *fsm);
92 SilcUInt32 silc_fsm_sema_timedwait(SilcFSMSema sema, void *fsm,
93                                    SilcUInt32 seconds, SilcUInt32 useconds,
94                                    SilcBool *ret_to);
95 void silc_fsm_sema_post(SilcFSMSema sema);
96
97 #endif /* SILCFSM_I_H */