|
@@ -61,6 +61,20 @@ action_dec(void *arg)
|
|
|
}
|
|
|
|
|
|
|
|
|
+static action_dec_to_0(void *arg)
|
|
|
+{
|
|
|
+ int *p = (int *)arg;
|
|
|
+ (*p)--;
|
|
|
+
|
|
|
+ if (*p <= -1) {
|
|
|
+ ck_abort_msg("Periodic timer called too often");
|
|
|
+ /* return 0 here would be unreachable code */
|
|
|
+ }
|
|
|
+
|
|
|
+ return (*p > 0);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
START_TEST(test_timer_cyclic)
|
|
|
{
|
|
|
struct mg_context ctx;
|
|
@@ -210,6 +224,80 @@ START_TEST(test_timer_oneshot_by_timer_add)
|
|
|
END_TEST
|
|
|
|
|
|
|
|
|
+START_TEST(test_timer_mixed)
|
|
|
+{
|
|
|
+ struct mg_context ctx;
|
|
|
+ int c[10];
|
|
|
+ memset(&ctx, 0, sizeof(ctx));
|
|
|
+ memset(c, 0, sizeof(c));
|
|
|
+
|
|
|
+ action_dec_ret = 0;
|
|
|
+
|
|
|
+ mark_point();
|
|
|
+ timers_init(&ctx);
|
|
|
+ mg_sleep(100);
|
|
|
+ mark_point();
|
|
|
+
|
|
|
+ /* 3 --> 2, because it is a single shot timer */
|
|
|
+ c[0] = 3;
|
|
|
+ timer_add(&ctx, 0, 0, 1, action_dec_to_0, c + 0);
|
|
|
+
|
|
|
+ /* 3 --> 0, because it will run until c[1] = 0 and then stop */
|
|
|
+ c[1] = 3;
|
|
|
+ timer_add(&ctx, 0, 0.2, 1, action_dec_to_0, c + 1);
|
|
|
+
|
|
|
+ /* 3 --> 1, with 750 ms period, it will run once at start,
|
|
|
+ * then once 750 ms later, but not 1500 ms later, since the
|
|
|
+ * timer is already stopped then. */
|
|
|
+ c[2] = 3;
|
|
|
+ timer_add(&ctx, 0, 0.75, 1, action_dec_to_0, c + 2);
|
|
|
+
|
|
|
+ /* 3 --> 2, will run at start, but no cyclic in 1 second */
|
|
|
+ c[3] = 3;
|
|
|
+ timer_add(&ctx, 0, 2.5, 1, action_dec_to_0, c + 3);
|
|
|
+
|
|
|
+ /* 3 --> 3, will not run at start */
|
|
|
+ c[4] = 3;
|
|
|
+ timer_add(&ctx, 2.5, 0.1, 1, action_dec_to_0, c + 4);
|
|
|
+
|
|
|
+ /* 3 --> 2, an absolute timer in the past (123.456) will still
|
|
|
+ * run once at start, and then with the period */
|
|
|
+ c[5] = 3;
|
|
|
+ timer_add(&ctx, 123.456, 2.5, 0, action_dec_to_0, c + 5);
|
|
|
+
|
|
|
+ /* 3 --> 1, an absolute timer in the past (123.456) will still
|
|
|
+ * run once at start, and then with the period */
|
|
|
+ c[6] = 3;
|
|
|
+ timer_add(&ctx, 123.456, 0.75, 0, action_dec_to_0, c + 6);
|
|
|
+
|
|
|
+ mark_point();
|
|
|
+
|
|
|
+ mg_sleep(1000); /* Sleep 1 second - timer will run */
|
|
|
+
|
|
|
+ mark_point();
|
|
|
+ ctx.stop_flag = 99; /* End timer thread */
|
|
|
+ mark_point();
|
|
|
+
|
|
|
+ mg_sleep(1000); /* Sleep 1 second - timer will not run */
|
|
|
+
|
|
|
+ mark_point();
|
|
|
+
|
|
|
+ timers_exit(&ctx);
|
|
|
+
|
|
|
+ mark_point();
|
|
|
+ mg_sleep(100);
|
|
|
+
|
|
|
+ ck_assert_int_eq(c[0], 2);
|
|
|
+ ck_assert_int_eq(c[1], 0);
|
|
|
+ ck_assert_int_eq(c[2], 1);
|
|
|
+ ck_assert_int_eq(c[3], 2);
|
|
|
+ ck_assert_int_eq(c[4], 3);
|
|
|
+ ck_assert_int_eq(c[5], 2);
|
|
|
+ ck_assert_int_eq(c[6], 1);
|
|
|
+}
|
|
|
+END_TEST
|
|
|
+
|
|
|
+
|
|
|
Suite *
|
|
|
make_timertest_suite(void)
|
|
|
{
|
|
@@ -217,6 +305,7 @@ make_timertest_suite(void)
|
|
|
|
|
|
TCase *const tcase_timer_cyclic = tcase_create("Timer Periodic");
|
|
|
TCase *const tcase_timer_oneshot = tcase_create("Timer Single Shot");
|
|
|
+ TCase *const tcase_timer_mixed = tcase_create("Timer Mixed");
|
|
|
|
|
|
tcase_add_test(tcase_timer_cyclic, test_timer_cyclic);
|
|
|
tcase_set_timeout(tcase_timer_cyclic, 30);
|
|
@@ -227,6 +316,10 @@ make_timertest_suite(void)
|
|
|
tcase_set_timeout(tcase_timer_oneshot, 30);
|
|
|
suite_add_tcase(suite, tcase_timer_oneshot);
|
|
|
|
|
|
+ tcase_add_test(tcase_timer_mixed, test_timer_mixed);
|
|
|
+ tcase_set_timeout(tcase_timer_mixed, 30);
|
|
|
+ suite_add_tcase(suite, tcase_timer_mixed);
|
|
|
+
|
|
|
return suite;
|
|
|
}
|
|
|
|
|
@@ -252,6 +345,7 @@ TIMER_PRIVATE(void)
|
|
|
test_timer_cyclic(0);
|
|
|
test_timer_oneshot_by_timer_add(0);
|
|
|
test_timer_oneshot_by_callback_retval(0);
|
|
|
+ test_timer_mixed(0);
|
|
|
|
|
|
mg_exit_library();
|
|
|
|