X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Ftests%2Ftest_silcfsm.c;h=782165f65c7ea09298259afa8ee40ca9e96487f1;hb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;hp=be2cd48d9a2a2322767d5aaa691bfd33c9bc7be8;hpb=c27a4ecc3e616e8a5ee09b8ca888ed6ff3e501f7;p=silc.git diff --git a/lib/silcutil/tests/test_silcfsm.c b/lib/silcutil/tests/test_silcfsm.c index be2cd48d..782165f6 100644 --- a/lib/silcutil/tests/test_silcfsm.c +++ b/lib/silcutil/tests/test_silcfsm.c @@ -1,6 +1,6 @@ /* SILC FSM tests */ -#include "silcincludes.h" +#include "silc.h" #include "silcfsm.h" typedef void (*Callback)(void *context); @@ -11,7 +11,7 @@ typedef struct FooStruct *Foo; typedef struct { SilcFSMThreadStruct thread; - SilcFSMSemaStruct sema; + SilcFSMEventStruct sema; SilcBool finished; int rounds; Foo f; @@ -22,16 +22,21 @@ struct FooStruct { SilcFSM fsm; SilcFSMThreadStruct thread; int timeout; - SilcFSMSemaStruct sema; + SilcFSMEventStruct sema; + SilcFSMEventStruct wait2; SilcSchedule schedule; Callback cb; void *cb_context; T threads[NUM_THREADS]; T threads2[NUM_THREADS]; + int c; + int got_wait1 : 1; + int got_wait2 : 1; }; SILC_FSM_STATE(test_st_start); SILC_FSM_STATE(test_st_second); +SILC_FSM_STATE(test_st_second_timeout); SILC_FSM_STATE(test_st_third); SILC_FSM_STATE(test_st_fourth); SILC_FSM_STATE(test_st_fifth); @@ -42,6 +47,11 @@ SILC_FSM_STATE(test_st_ninth); SILC_FSM_STATE(test_st_tenth); SILC_FSM_STATE(test_st_finish); +SILC_FSM_STATE(test_st_wait1); +SILC_FSM_STATE(test_st_wait2); +SILC_FSM_STATE(test_st_signal1); +SILC_FSM_STATE(test_st_signal1_check); + SILC_FSM_STATE(test_thread_st_start); SILC_FSM_STATE(test_thread_st_finish); SILC_FSM_STATE(test_thread2_st_start); @@ -49,6 +59,12 @@ SILC_FSM_STATE(test_thread2_st_finish); SILC_FSM_STATE(test_thread3_st_start); SILC_FSM_STATE(test_thread4_st_start); +static void test_fsm_destr(SilcFSMThread thread, void *thread_context, + void *user_context) +{ + silc_fsm_free(thread); +} + SILC_TASK_CALLBACK(async_call_timeout) { Foo f = context; @@ -80,9 +96,35 @@ SILC_FSM_STATE(test_st_second) { SILC_LOG_DEBUG(("test_st_second")); - /** Move to third state, timeout */ + /** Move to second timeout state, timeout */ SILC_LOG_DEBUG(("Move to next state with 2 second timeout")); - silc_fsm_next_later(fsm, test_st_third, 2, 0); + silc_fsm_next_later(fsm, test_st_second_timeout, 2, 0); + return SILC_FSM_WAIT; +} + +SILC_TASK_CALLBACK(test_second_timeout) +{ + Foo f = context; + SILC_LOG_DEBUG(("test_second_timeout")); + + SILC_LOG_DEBUG(("Interrupt 3 second wait and continue immediately")); + f->c++; + silc_fsm_next(f->fsm, test_st_third); + silc_fsm_continue(f->fsm); +} + +SILC_FSM_STATE(test_st_second_timeout) +{ + Foo f = fsm_context; + + SILC_LOG_DEBUG(("test_st_second_timeout")); + + /** Move to third state, timeout */ + SILC_LOG_DEBUG(("Move to next state with 3 second timeout")); + SILC_LOG_DEBUG(("The timeout will be interrupted with silc_fsm_continue")); + silc_fsm_next_later(fsm, test_st_third, 3, 0); + silc_schedule_task_add_timeout(silc_fsm_get_schedule(fsm), + test_second_timeout, f, 2, 500000); return SILC_FSM_WAIT; } @@ -99,6 +141,9 @@ SILC_FSM_STATE(test_st_third) SILC_LOG_DEBUG(("test_st_third")); + f->c++; + assert(f->c == 2); + f->fsm = fsm; /** Wait async callback*/ @@ -110,28 +155,76 @@ SILC_FSM_STATE(test_st_third) SILC_FSM_STATE(test_st_fourth) { Foo f = fsm_context; + SilcFSMThread t; SILC_LOG_DEBUG(("test_st_fourth")); f->timeout = 1; SILC_LOG_DEBUG(("Creating FSM thread")); - if (!silc_fsm_thread_init(&f->thread, fsm, f, NULL, NULL, FALSE)) { - /** Error creating thread */ - SILC_LOG_DEBUG(("Error creating thread")); - f->error = TRUE; - silc_fsm_next(fsm, test_st_finish); - return SILC_FSM_CONTINUE; - } + silc_fsm_thread_init(&f->thread, fsm, f, NULL, NULL, FALSE); SILC_LOG_DEBUG(("Starting thread")); + /*** Start thread */ silc_fsm_start(&f->thread, test_thread_st_start); + SILC_LOG_DEBUG(("Creating two waiting threads")); + silc_fsm_event_init(&f->wait2, fsm); + t = silc_fsm_thread_alloc(fsm, f, test_fsm_destr, NULL, FALSE); + silc_fsm_start(t, test_st_wait1); + t = silc_fsm_thread_alloc(fsm, f, test_fsm_destr, NULL, FALSE); + silc_fsm_start(t, test_st_wait2); + + SILC_LOG_DEBUG(("Create signaller thread")); + t = silc_fsm_thread_alloc(fsm, f, test_fsm_destr, NULL, FALSE); + silc_fsm_start(t, test_st_signal1); + /** Waiting thread to terminate */ SILC_LOG_DEBUG(("Waiting for thread to terminate")); silc_fsm_next(fsm, test_st_fifth); SILC_FSM_THREAD_WAIT(&f->thread); } +SILC_FSM_STATE(test_st_wait1) +{ + Foo f = fsm_context; + + SILC_LOG_DEBUG(("Waiter 1")); + SILC_FSM_EVENT_WAIT(&f->wait2); + SILC_LOG_DEBUG(("Waiter 1 signalled")); + f->got_wait1 = 1; + return SILC_FSM_FINISH; +} + +SILC_FSM_STATE(test_st_wait2) +{ + Foo f = fsm_context; + + SILC_LOG_DEBUG(("Waiter 2")); + SILC_FSM_EVENT_WAIT(&f->wait2); + SILC_LOG_DEBUG(("Waiter 2 signalled")); + f->got_wait2 = 1; + return SILC_FSM_FINISH; +} + +SILC_FSM_STATE(test_st_signal1) +{ + Foo f = fsm_context; + + SILC_LOG_DEBUG(("Signaller 1")); + SILC_FSM_EVENT_SIGNAL(&f->wait2); + silc_fsm_next_later(fsm, test_st_signal1_check, 0, 500000); + return SILC_FSM_WAIT;; +} + +SILC_FSM_STATE(test_st_signal1_check) +{ + Foo f = fsm_context; + + SILC_LOG_DEBUG(("Signal check")); + assert(f->got_wait1 && f->got_wait2); + return SILC_FSM_FINISH; +} + SILC_FSM_STATE(test_thread_st_start) { Foo f = fsm_context; @@ -161,24 +254,18 @@ SILC_FSM_STATE(test_st_fifth) f->timeout = 7; - SILC_LOG_DEBUG(("Creating FSM semaphore")); - silc_fsm_sema_init(&f->sema, fsm, 0); + SILC_LOG_DEBUG(("Creating FSM event")); + silc_fsm_event_init(&f->sema, fsm); SILC_LOG_DEBUG(("Creating FSM thread")); - if (!silc_fsm_thread_init(&f->thread, fsm, f, NULL, NULL, TRUE)) { - /** Error creating real thread */ - SILC_LOG_DEBUG(("Error creating thread")); - f->error = TRUE; - silc_fsm_next(fsm, test_st_finish); - return SILC_FSM_CONTINUE; - } + silc_fsm_thread_init(&f->thread, fsm, f, NULL, NULL, TRUE); SILC_LOG_DEBUG(("Starting thread")); silc_fsm_start(&f->thread, test_thread2_st_start); /** Waiting thread to terminate, timeout */ SILC_LOG_DEBUG(("Waiting for thread to terminate for 5 seconds")); silc_fsm_next(fsm, test_st_sixth); - SILC_FSM_SEMA_TIMEDWAIT(&f->sema, 5, 0); + SILC_FSM_EVENT_TIMEDWAIT(&f->sema, 5, 0, NULL); return SILC_FSM_CONTINUE; } @@ -200,7 +287,7 @@ SILC_FSM_STATE(test_thread2_st_finish) SILC_LOG_DEBUG(("test_thread2_st_finish")); SILC_LOG_DEBUG(("Post semaphore")); - SILC_FSM_SEMA_POST(&f->sema); + SILC_FSM_EVENT_SIGNAL(&f->sema); SILC_LOG_DEBUG(("Finishing the thread")); return SILC_FSM_FINISH; @@ -223,7 +310,7 @@ SILC_FSM_STATE(test_thread3_st_start) T *t = fsm_context; if (t->rounds == 0) { - SILC_FSM_SEMA_POST(&t->sema); + SILC_FSM_EVENT_SIGNAL(&t->sema); return SILC_FSM_FINISH; } @@ -246,16 +333,9 @@ SILC_FSM_STATE(test_st_seventh) for (i = 0; i < NUM_THREADS; i++) { f->threads[i].rounds = 10; f->threads[i].f = f; - silc_fsm_sema_init(&f->threads[i].sema, fsm, 0); - if (!silc_fsm_thread_init(&f->threads[i].thread, fsm, - &f->threads[i], NULL, NULL, FALSE)) { - /** Error creating thread */ - SILC_LOG_DEBUG(("Error creating thread")); - f->error = TRUE; - silc_fsm_next(fsm, test_st_finish); - return SILC_FSM_CONTINUE; - } - + silc_fsm_event_init(&f->threads[i].sema, fsm); + silc_fsm_thread_init(&f->threads[i].thread, fsm, + &f->threads[i], NULL, NULL, FALSE); silc_fsm_start(&f->threads[i].thread, test_thread3_st_start); } @@ -271,14 +351,11 @@ SILC_FSM_STATE(test_st_eighth) for (i = 0; i < NUM_THREADS; i++) { if (f->threads[i].finished == FALSE) { - SILC_FSM_SEMA_WAIT(&f->threads[i].sema); + SILC_FSM_EVENT_WAIT(&f->threads[i].sema); f->threads[i].finished = TRUE; } } - for (i = 0; i < NUM_THREADS; i++) - silc_fsm_uninit(&f->threads[i].thread); - SILC_LOG_DEBUG(("All %d threads terminated", NUM_THREADS)); /** Move to next thread */ @@ -291,7 +368,7 @@ SILC_FSM_STATE(test_thread4_st_start) T *t = fsm_context; if (t->rounds == 0) { - SILC_FSM_SEMA_POST(&t->sema); + SILC_FSM_EVENT_SIGNAL(&t->sema); return SILC_FSM_FINISH; } @@ -309,23 +386,16 @@ SILC_FSM_STATE(test_st_ninth) SILC_LOG_DEBUG(("test_st_ninth")); - SILC_LOG_DEBUG(("Creating FSM semaphore")); - silc_fsm_sema_init(&f->sema, fsm, NUM_THREADS + 1); + SILC_LOG_DEBUG(("Creating FSM event")); + silc_fsm_event_init(&f->sema, fsm); SILC_LOG_DEBUG(("Creating %d real FSM threads", NUM_THREADS)); for (i = 0; i < NUM_THREADS; i++) { f->threads2[i].rounds = 10; f->threads2[i].f = f; - silc_fsm_sema_init(&f->threads2[i].sema, fsm, 0); - if (!silc_fsm_thread_init(&f->threads2[i].thread, fsm, - &f->threads2[i], NULL, NULL, TRUE)) { - /** Error creating real thread */ - SILC_LOG_DEBUG(("Error creating real thread")); - f->error = TRUE; - silc_fsm_next(fsm, test_st_finish); - return SILC_FSM_CONTINUE; - } - + silc_fsm_event_init(&f->threads2[i].sema, fsm); + silc_fsm_thread_init(&f->threads2[i].thread, fsm, + &f->threads2[i], NULL, NULL, TRUE); silc_fsm_start(&f->threads2[i].thread, test_thread4_st_start); } @@ -341,13 +411,10 @@ SILC_FSM_STATE(test_st_tenth) for (i = 0; i < NUM_THREADS; i++) if (f->threads2[i].finished == FALSE) { - SILC_FSM_SEMA_WAIT(&f->threads2[i].sema); + SILC_FSM_EVENT_WAIT(&f->threads2[i].sema); f->threads2[i].finished = TRUE; } - for (i = 0; i < NUM_THREADS; i++) - silc_fsm_uninit(&f->threads2[i].thread); - SILC_LOG_DEBUG(("All %d real threads terminated", NUM_THREADS)); /** Finished successfully */ @@ -383,11 +450,11 @@ int main(int argc, char **argv) silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); silc_log_quick(TRUE); - silc_log_set_debug_string("*fsm*,*async*"); + silc_log_set_debug_string("*fsm*,*async*,*errno*"); } SILC_LOG_DEBUG(("Allocating scheduler")); - schedule = silc_schedule_init(0, NULL); + schedule = silc_schedule_init(0, NULL, NULL); f = silc_calloc(1, sizeof(*f)); if (!f) @@ -395,7 +462,7 @@ int main(int argc, char **argv) f->schedule = schedule; SILC_LOG_DEBUG(("Allocating FSM context")); - fsm = silc_fsm_alloc(f, destructor, f, schedule); + f->fsm = fsm = silc_fsm_alloc(f, destructor, f, schedule); if (!fsm) goto err; silc_fsm_start(fsm, test_st_start);