Initial code commit for Toolkit 1.1.
[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   SilcUInt32 value;                     /* Current semaphore value */
34 };
35
36 /* FSM and FSM thread context */
37 struct SilcFSMObject {
38   struct SilcFSMObject *next;
39   void *fsm_context;                    /* Caller's context */
40   SilcSchedule schedule;                /* Scheduler */
41   SilcFSMSema sema;                     /* Valid if waiting sema timeout */
42   SilcFSMStateCallback next_state;      /* Next state in machine */
43   SilcFSMDestructor destructor;         /* Destructor */
44   void *destructor_context;
45   union {
46     /* Machine */
47     struct {
48       SilcUInt32 threads;               /* Number of threads */
49       SilcMutex lock;                   /* Lock, valid if using real threads */
50     } m;
51
52     /* Thread */
53     struct {
54       struct SilcFSMObject *fsm;        /* Machine */
55       SilcFSMSema sema;                 /* Semaphore for waiting termination */
56     } t;
57   } u;
58   unsigned int thread           : 1;    /* Set if this is thread */
59   unsigned int real_thread      : 1;    /* Set if to use real threads */
60   unsigned int async_call       : 1;    /* Set if called real async call */
61   unsigned int finished         : 1;    /* Set if SILC_FSM_FINISH returned */
62   unsigned int sema_timedout    : 1;    /* Set if waiting sema timedout */
63   unsigned int synchronous      : 1;    /* Set if silc_fsm_start_sync called */
64 };
65
66 /* Used internally by the SILC_FSM_CALL macros to detect whether async
67    call is really async or not. */
68 static inline
69 bool silc_fsm_set_call(struct SilcFSMObject *fsm, bool async_call)
70 {
71   bool old = fsm->async_call;
72   fsm->async_call = async_call;
73   return old;
74 }
75
76 /* Continues after callback */
77 void silc_fsm_continue(void *fsm);
78 void silc_fsm_continue_sync(void *fsm);
79
80 /* Wait for thread to terminate */
81 bool silc_fsm_thread_wait(void *fsm, void *thread);
82
83 /* Semaphores */
84 SilcUInt32 silc_fsm_sema_wait(SilcFSMSema sema, void *fsm);
85 SilcUInt32 silc_fsm_sema_timedwait(SilcFSMSema sema, void *fsm,
86                                    SilcUInt32 seconds, SilcUInt32 useconds);
87 void silc_fsm_sema_post(SilcFSMSema sema);
88
89 #endif /* SILCFSM_I_H */