silc_fsm_continue[_sync] cancels silc_fsm_next_later timeout.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 7 Nov 2006 16:44:40 +0000 (16:44 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 7 Nov 2006 16:44:40 +0000 (16:44 +0000)
lib/silcutil/silcfsm.c
lib/silcutil/silcfsm.h
lib/silcutil/silcfsm_i.h

index ae841d6d59e349863a54e5086eb10e79ddc7da47..d1b0dff965212ca6996f7d7ef45998978f7ba812 100644 (file)
@@ -245,6 +245,7 @@ void silc_fsm_next_later(void *fsm, SilcFSMStateCallback next_state,
     return;
   silc_schedule_task_add_timeout(f->schedule, silc_fsm_run, f,
                                 seconds, useconds);
+  f->next_later = TRUE;
 }
 
 /* Continue after callback or async operation */
@@ -252,7 +253,12 @@ void silc_fsm_next_later(void *fsm, SilcFSMStateCallback next_state,
 void silc_fsm_continue(void *fsm)
 {
   SilcFSM f = fsm;
-  silc_schedule_task_add_timeout(f->schedule, silc_fsm_run, f, 0, 1);
+  if (f->next_later) {
+    silc_schedule_task_del_by_all(f->schedule, 0, silc_fsm_run, f);
+    f->next_later = FALSE;
+  }
+  if (!silc_schedule_task_add_timeout(f->schedule, silc_fsm_run, f, 0, 1))
+    silc_fsm_run(f->schedule, silc_schedule_get_context(f->schedule), 0, 0, f);
 }
 
 /* Continue after callback or async operation immediately */
@@ -260,6 +266,10 @@ void silc_fsm_continue(void *fsm)
 void silc_fsm_continue_sync(void *fsm)
 {
   SilcFSM f = fsm;
+  if (f->next_later) {
+    silc_schedule_task_del_by_all(f->schedule, 0, silc_fsm_run, f);
+    f->next_later = FALSE;
+  }
   silc_fsm_run(f->schedule, silc_schedule_get_context(f->schedule), 0, 0, f);
 }
 
index 8468c4fd2e2bda1018fc7490b9440e838484cae0..0c7a9679dac458bf62ab201ad91e06b2b491d20d 100644 (file)
@@ -629,6 +629,10 @@ void silc_fsm_next(void *fsm, SilcFSMStateCallback next_state);
  *    If both `seconds' and `useconds' are 0, the effect is same as calling
  *    silc_fsm_next function, and SILC_FSM_CONTINUE must be returned.
  *
+ *    If silc_fsm_continue or silc_fsm_continue_sync is called while the
+ *    machine or thread is in SILC_FSM_WAIT state the timeout is automatically
+ *    canceled and the state moves to the next state.
+ *
  * EXAMPLE
  *
  *    // Move to next state after 10 seconds
index 9246878f0904c860ce46f1eaad688875fd52a18c..53b7ce3394fba18abf8042b5127d6ac26ce003a3 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
@@ -64,6 +64,7 @@ struct SilcFSMObject {
   unsigned int finished         : 1;    /* Set if SILC_FSM_FINISH returned */
   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 */
 };
 
 /* Semaphore post context */