From 270b3a27b2f2e0d6c7a4c400f371f22cdd6fb480 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Tue, 7 Nov 2006 16:44:40 +0000 Subject: [PATCH] silc_fsm_continue[_sync] cancels silc_fsm_next_later timeout. --- lib/silcutil/silcfsm.c | 12 +++++++++++- lib/silcutil/silcfsm.h | 4 ++++ lib/silcutil/silcfsm_i.h | 3 ++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/silcutil/silcfsm.c b/lib/silcutil/silcfsm.c index ae841d6d..d1b0dff9 100644 --- a/lib/silcutil/silcfsm.c +++ b/lib/silcutil/silcfsm.c @@ -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); } diff --git a/lib/silcutil/silcfsm.h b/lib/silcutil/silcfsm.h index 8468c4fd..0c7a9679 100644 --- a/lib/silcutil/silcfsm.h +++ b/lib/silcutil/silcfsm.h @@ -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 diff --git a/lib/silcutil/silcfsm_i.h b/lib/silcutil/silcfsm_i.h index 9246878f..53b7ce33 100644 --- a/lib/silcutil/silcfsm_i.h +++ b/lib/silcutil/silcfsm_i.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - 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 */ -- 2.43.0