X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcfsm.c;h=3382713ed50276c90c1c84975727f901dc113a31;hb=52e57c880aba9c5e89f59d962eb9af75670b76e0;hp=0098bf2f551ade169311ca8b438769be5e09719c;hpb=8fd8212bcd16f2b53fbedff2a9b9a4e8c15b9695;p=silc.git diff --git a/lib/silcutil/silcfsm.c b/lib/silcutil/silcfsm.c index 0098bf2f..3382713e 100644 --- a/lib/silcutil/silcfsm.c +++ b/lib/silcutil/silcfsm.c @@ -151,6 +151,9 @@ SILC_TASK_CALLBACK(silc_fsm_free_final) if (f->thread && f->u.t.event) silc_fsm_event_free(f->u.t.event); + if (!f->thread) + silc_atomic_uninit32(&f->u.m.threads); + silc_free(f); } @@ -207,6 +210,7 @@ void silc_fsm_start(void *fsm, SilcFSMStateCallback start_state) silc_fsm_start_real_thread(f->schedule, silc_schedule_get_context(f->schedule), 0, 0, f); + silc_schedule_wakeup(f->schedule); return; } @@ -259,12 +263,18 @@ void silc_fsm_next_later(void *fsm, SilcFSMStateCallback next_state, SilcUInt32 seconds, SilcUInt32 useconds) { SilcFSM f = fsm; + f->next_state = next_state; if (!seconds && !useconds) return; + silc_schedule_task_add_timeout(f->schedule, silc_fsm_run, f, seconds, useconds); f->next_later = TRUE; + + /* Wakeup up the scheduler just in case this was called from another + thread. */ + silc_schedule_wakeup(f->schedule); } /* Continue after callback or async operation */ @@ -272,12 +282,19 @@ void silc_fsm_next_later(void *fsm, SilcFSMStateCallback next_state, void silc_fsm_continue(void *fsm) { SilcFSM f = fsm; + if (f->next_later) { + /* Cancel next_later timeout */ 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, 0)) silc_fsm_run(f->schedule, silc_schedule_get_context(f->schedule), 0, 0, f); + + /* Wakeup up the scheduler just in case this was called from another + thread. */ + silc_schedule_wakeup(f->schedule); } /* Continue after callback or async operation immediately */ @@ -300,10 +317,6 @@ void silc_fsm_finish(void *fsm) SILC_ASSERT(!f->finished); - /* Machine must not have active threads */ - if (!f->thread && silc_atomic_get_int32(&f->u.m.threads)) - assert(silc_atomic_get_int32(&f->u.m.threads) == 0); - f->started = FALSE; f->finished = TRUE; @@ -467,11 +480,13 @@ SILC_TASK_CALLBACK(silc_fsm_finish_fsm) fsm->destructor(fsm, fsm->fsm_context, fsm->destructor_context); } else { + /* Machine must not have active threads */ + assert(silc_atomic_get_int32(&fsm->u.m.threads) == 0); + if (fsm->u.m.lock) { silc_mutex_free(fsm->u.m.lock); fsm->u.m.lock = NULL; } - silc_atomic_uninit32(&fsm->u.m.threads); /* Call the destructor callback. */ if (fsm->destructor)