Added SILC Thread Queue API
[silc.git] / lib / silcutil / silcfsm_i.h
index 9246878f0904c860ce46f1eaad688875fd52a18c..50475da5ca7c4d5204b2539eecaea5a8c68762d9 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2005 Pekka Riikonen
+  Copyright (C) 2005 - 2006 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
 #error "Do not include this header directly"
 #endif
 
-/* Semaphore structure, holds list of FSM machines that are waiting
-   for this semaphore.  The SilcFSM has *next; pointer that is used
-   with SilcList. */
-struct SilcFSMSemaObject {
+/* FSM state status */
+typedef enum {
+  SILC_FSM_ST_CONTINUE,             /* Continue immediately to next state */
+  SILC_FSM_ST_YIELD,        /* Continue to next state through scheduler */
+  SILC_FSM_ST_WAIT,         /* Wait for some async call or timeout */
+  SILC_FSM_ST_FINISH,       /* Finish state machine and call destructor
+                               through scheduler */
+} SilcFSMStatus;
+
+/* Event structure, holds list of FSM machines that are waiting for this
+   event.  The SilcFSM has *next; pointer that is used with SilcList.
+   Internally events act as semaphore counters. */
+struct SilcFSMEventObject {
   SilcFSM fsm;                         /* Machine */
   SilcList waiters;                    /* List of SilcFSM pointers */
-  unsigned int value     : 21;         /* Current semaphore value */
+  unsigned int value     : 21;         /* Current event semaphore value */
   unsigned int refcnt    : 10;         /* Reference counter */
   unsigned int allocated : 1;          /* Set if allocated */
 };
@@ -40,7 +49,7 @@ struct SilcFSMObject {
   struct SilcFSMObject *next;
   void *fsm_context;                   /* Caller's context */
   SilcSchedule schedule;               /* Scheduler */
-  SilcFSMSema sema;                    /* Valid if waiting sema timeout */
+  SilcFSMEvent event;                  /* Valid if waiting event timeout */
   SilcFSMStateCallback next_state;     /* Next state in machine */
   void *state_context;                 /* Extra state specific context */
   SilcFSMDestructor destructor;                /* Destructor */
@@ -48,29 +57,31 @@ struct SilcFSMObject {
   union {
     /* Machine */
     struct {
-      SilcUInt32 threads;              /* Number of threads */
+      SilcAtomic32 threads;            /* Number of threads */
       SilcMutex lock;                  /* Lock, valid if using real threads */
     } m;
 
     /* Thread */
     struct {
       struct SilcFSMObject *fsm;       /* Machine */
-      SilcFSMSema sema;                        /* Semaphore for waiting termination */
+      SilcFSMEvent event;               /* Event for waiting termination */
     } t;
   } u;
   unsigned int thread           : 1;   /* Set if this is thread */
   unsigned int real_thread      : 1;    /* Set if to use real threads */
   unsigned int async_call       : 1;    /* Set if called real async call */
   unsigned int finished         : 1;    /* Set if SILC_FSM_FINISH returned */
-  unsigned int sema_timedout    : 1;    /* Set if waiting sema timedout */
+  unsigned int event_timedout   : 1;    /* Set if waiting event timedout */
   unsigned int synchronous      : 1;    /* Set if silc_fsm_start_sync called */
+  unsigned int next_later       : 1;    /* Set if silc_fsm_next_later called */
+  unsigned int started          : 1;    /* Set when started and not finished */
 };
 
-/* Semaphore post context */
+/* Event signal context */
 typedef struct {
-  SilcFSMSema sema;                    /* Semaphore */
+  SilcFSMEvent event;                  /* Event */
   SilcFSM fsm;                         /* Signalled FSM */
-} *SilcFSMSemaPost;
+} *SilcFSMEventSignal;
 
 /* Used internally by the SILC_FSM_CALL macros to detect whether async
    call is really async or not. */
@@ -85,11 +96,11 @@ SilcBool silc_fsm_set_call(struct SilcFSMObject *fsm, SilcBool async_call)
 /* Wait for thread to terminate */
 SilcBool silc_fsm_thread_wait(void *fsm, void *thread);
 
-/* Semaphores */
-SilcUInt32 silc_fsm_sema_wait(SilcFSMSema sema, void *fsm);
-SilcUInt32 silc_fsm_sema_timedwait(SilcFSMSema sema, void *fsm,
-                                  SilcUInt32 seconds, SilcUInt32 useconds,
-                                  SilcBool *ret_to);
-void silc_fsm_sema_post(SilcFSMSema sema);
+/* Events */
+SilcUInt32 silc_fsm_event_wait(SilcFSMEvent event, void *fsm);
+SilcUInt32 silc_fsm_event_timedwait(SilcFSMEvent event, void *fsm,
+                                   SilcUInt32 seconds, SilcUInt32 useconds,
+                                   SilcBool *ret_to);
+void silc_fsm_event_signal(SilcFSMEvent event);
 
 #endif /* SILCFSM_I_H */