Added SILC Server library.
[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 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 };
68
69 /* Semaphore post context */
70 typedef struct {
71   SilcFSMSema sema;                     /* Semaphore */
72   SilcFSM fsm;                          /* Signalled FSM */
73 } *SilcFSMSemaPost;
74
75 /* Used internally by the SILC_FSM_CALL macros to detect whether async
76    call is really async or not. */
77 static inline
78 SilcBool silc_fsm_set_call(struct SilcFSMObject *fsm, SilcBool async_call)
79 {
80   SilcBool old = fsm->async_call;
81   fsm->async_call = async_call;
82   return old;
83 }
84
85 /* Wait for thread to terminate */
86 SilcBool silc_fsm_thread_wait(void *fsm, void *thread);
87
88 /* Semaphores */
89 SilcUInt32 silc_fsm_sema_wait(SilcFSMSema sema, void *fsm);
90 SilcUInt32 silc_fsm_sema_timedwait(SilcFSMSema sema, void *fsm,
91                                    SilcUInt32 seconds, SilcUInt32 useconds,
92                                    SilcBool *ret_to);
93 void silc_fsm_sema_post(SilcFSMSema sema);
94
95 #endif /* SILCFSM_I_H */