Added asynchronous event tasks to SILC Scheduler. Added
[crypto.git] / lib / silcutil / silcfsm.c
index d87e0406cd5d83b14f4c34c8d0e8104899dfa04e..2ded983253aa77906cd439210b69306afe92116c 100644 (file)
@@ -58,8 +58,13 @@ SilcBool silc_fsm_init(SilcFSM fsm,
                       void *destructor_context,
                       SilcSchedule schedule)
 {
-  if (!schedule)
-    return FALSE;
+  if (!schedule) {
+    schedule = silc_schedule_get_global();
+    if (!schedule) {
+      silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+      return FALSE;
+    }
+  }
 
   fsm->fsm_context = fsm_context;
   fsm->state_context = NULL;
@@ -106,7 +111,7 @@ void silc_fsm_thread_init(SilcFSMThread thread,
   SILC_LOG_DEBUG(("Initializing new thread %p (%s)",
                  thread, real_thread ? "real" : "FSM"));
 
-  SILC_ASSERT(!fsm->thread);
+  SILC_VERIFY(!fsm->thread);
 
   thread->fsm_context = thread_context;
   thread->state_context = NULL;
@@ -315,7 +320,7 @@ void silc_fsm_finish(void *fsm)
 {
   SilcFSM f = fsm;
 
-  SILC_ASSERT(!f->finished);
+  SILC_VERIFY(!f->finished);
 
   f->started = FALSE;
   f->finished = TRUE;
@@ -354,7 +359,7 @@ SilcSchedule silc_fsm_get_schedule(void *fsm)
 
 SilcFSM silc_fsm_get_machine(SilcFSMThread thread)
 {
-  SILC_ASSERT(thread->thread);
+  SILC_VERIFY(thread->thread);
   return (SilcFSM)thread->u.t.fsm;
 }
 
@@ -404,7 +409,7 @@ SilcBool silc_fsm_thread_wait(void *fsm, void *thread)
 {
   SilcFSM t = thread;
 
-  SILC_ASSERT(t->thread);
+  SILC_VERIFY(t->thread);
 
   t->u.t.event = silc_fsm_event_alloc(t->u.t.fsm);
   if (!t->u.t.event)
@@ -481,7 +486,7 @@ SILC_TASK_CALLBACK(silc_fsm_finish_fsm)
 
   } else {
     /* Machine must not have active threads */
-    assert(silc_atomic_get_int32(&fsm->u.m.threads) == 0);
+    SILC_VERIFY(silc_atomic_get_int32(&fsm->u.m.threads) == 0);
 
     if (fsm->u.m.lock) {
       silc_mutex_free(fsm->u.m.lock);
@@ -515,7 +520,7 @@ SilcFSMEvent silc_fsm_event_alloc(SilcFSM fsm)
 void silc_fsm_event_init(SilcFSMEvent event, SilcFSM fsm)
 {
   SILC_LOG_DEBUG(("Initializing event %p", event));
-  SILC_ASSERT(!fsm->thread);
+  SILC_VERIFY(!fsm->thread);
   memset(event, 0, sizeof(*event));
   event->fsm = fsm;
   event->refcnt = 0;
@@ -765,12 +770,15 @@ void *silc_fsm_thread(void *context)
   /* We allocate new SilcSchedule for the FSM, as the old SilcSchedule
      cannot be used in this thread.  Application may still use it if it
      wants but we use our own. */
-  fsm->schedule = silc_schedule_init(0, old, silc_schedule_get_stack(old));
+  fsm->schedule = silc_schedule_init(0, old, silc_schedule_get_stack(old), old);
   if (silc_unlikely(!fsm->schedule)) {
     fsm->schedule = old;
     return NULL;
   }
 
+  /* The new scheduler is a global scheduler in this thread */
+  silc_schedule_set_global(fsm->schedule);
+
   /* Start the FSM thread */
   if (silc_unlikely(!silc_schedule_task_add_timeout(fsm->schedule,
                                                    silc_fsm_run, fsm, 0, 0))) {
@@ -782,6 +790,9 @@ void *silc_fsm_thread(void *context)
   /* Run the scheduler */
   silc_schedule(fsm->schedule);
 
+  /* Reset global scheduler */
+  silc_schedule_set_global(NULL);
+
   /* Free resources */
   silc_schedule_uninit(fsm->schedule);