+/* Finish FSM */
+
+void silc_fsm_finish(void *fsm)
+{
+ SilcFSM f = fsm;
+
+ SILC_ASSERT(!f->finished);
+ f->finished = TRUE;
+
+ /* If we are thread and using real threads, the FSM thread will finish
+ after the real thread has finished, in the main thread. */
+ if (f->thread && f->real_thread) {
+ /* Stop the real thread's scheduler to finish the thread */
+ silc_schedule_stop(f->schedule);
+ silc_schedule_wakeup(f->schedule);
+ return;
+ }
+
+ /* Normal FSM operation */
+ if (f->synchronous)
+ silc_fsm_finish_fsm(f->schedule, silc_schedule_get_context(f->schedule),
+ 0, 0, fsm);
+ else
+ silc_schedule_task_add_timeout(f->schedule, silc_fsm_finish_fsm, f, 0, 1);
+}
+