Added silc_fsm_is_started.
authorPekka Riikonen <priikone@silcnet.org>
Sun, 10 Dec 2006 16:07:49 +0000 (16:07 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 10 Dec 2006 16:07:49 +0000 (16:07 +0000)
lib/silcutil/silcfsm.c
lib/silcutil/silcfsm.h
lib/silcutil/silcfsm_i.h

index f22abd6791a13976c44140a5d0444b04a09447be..5cd81e1969a2e59786c7532f11c17242187fcf9d 100644 (file)
@@ -68,6 +68,7 @@ SilcBool silc_fsm_init(SilcFSM fsm,
   fsm->schedule = schedule;
   fsm->thread = FALSE;
   fsm->async_call = FALSE;
+  fsm->started = FALSE;
   fsm->u.m.threads = 0;
   fsm->u.m.lock = NULL;
 
@@ -114,6 +115,7 @@ void silc_fsm_thread_init(SilcFSMThread thread,
   thread->schedule = fsm->schedule;
   thread->thread = TRUE;
   thread->async_call = FALSE;
+  thread->started = FALSE;
   thread->real_thread = real_thread;
   thread->u.t.fsm = fsm;
 
@@ -157,7 +159,11 @@ SILC_TASK_CALLBACK(silc_fsm_free_final)
 void silc_fsm_free(void *fsm)
 {
   SilcFSM f = fsm;
-  silc_schedule_task_add_timeout(f->schedule, silc_fsm_free_final, f, 0, 0);
+  if (!f->thread)
+    silc_schedule_task_add_timeout(f->schedule, silc_fsm_free_final, f, 0, 0);
+  else
+    silc_fsm_free_final(f->schedule, silc_schedule_get_context(f->schedule),
+                       0, 0, f);
 }
 
 /* Task to start real thread. We start threads through scheduler, not
@@ -190,6 +196,7 @@ void silc_fsm_start(void *fsm, SilcFSMStateCallback start_state)
   f->finished = FALSE;
   f->next_state = start_state;
   f->synchronous = FALSE;
+  f->started = TRUE;
 
   /* Start real thread through scheduler */
   if (f->thread && f->real_thread) {
@@ -213,6 +220,7 @@ void silc_fsm_start_sync(void *fsm, SilcFSMStateCallback start_state)
   f->finished = FALSE;
   f->next_state = start_state;
   f->synchronous = TRUE;
+  f->started = TRUE;
 
   /* Start real thread directly */
   if (f->thread && f->real_thread) {
@@ -281,6 +289,10 @@ void silc_fsm_finish(void *fsm)
 
   SILC_ASSERT(!f->finished);
   f->finished = TRUE;
+  f->started = FALSE;
+
+  silc_schedule_task_del_by_all(f->schedule, 0, silc_fsm_run, f);
+  f->next_later = FALSE;
 
   /* If we are thread and using real threads, the FSM thread will finish
      after the real thread has finished, in the main thread. */
@@ -315,6 +327,18 @@ SilcFSM silc_fsm_get_machine(SilcFSMThread thread)
   return (SilcFSM)thread->u.t.fsm;
 }
 
+/* Returns TRUE if FSM is started and not yet finished */
+
+SilcBool silc_fsm_is_started(void *fsm)
+{
+  SilcFSM f = fsm;
+
+  if (f->started && !f->finished)
+    return TRUE;
+
+  return FALSE;
+}
+
 /* Set context */
 
 void silc_fsm_set_context(void *fsm, void *fsm_context)
index b7413afee2ca67d152524cf824bbdc5a477d5060..2f27184e5fe2ca43b54ff8d26a56455db7050faf 100644 (file)
@@ -797,6 +797,20 @@ SilcSchedule silc_fsm_get_schedule(void *fsm);
  ***/
 SilcFSM silc_fsm_get_machine(SilcFSMThread thread);
 
+/****f* silcutil/SilcFSMAPI/silc_fsm_is_started
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool silc_fsm_is_started(void *fsm);
+ *
+ * DESCRIPTION
+ *
+ *    Returns TRUE if the machine or thread `fsm' has been started and has
+ *    not been finished yet.  This function is used with both SilcFSM and
+ *    SilcFSMThread contexts.
+ *
+ ***/
+SilcBool silc_fsm_is_started(void *fsm);
 
 /* FSM Semaphores */
 
index 53b7ce3394fba18abf8042b5127d6ac26ce003a3..09c167b66683fead0c7d7ed3b7d02adabe4b76b6 100644 (file)
@@ -65,6 +65,7 @@ struct SilcFSMObject {
   unsigned int sema_timedout    : 1;    /* Set if waiting sema 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 */