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