Skip to content

Commit 97c7c91

Browse files
authored
Merge pull request #14087 from adbridge/events
Update events period method to check for invalid values
2 parents dde7b22 + 81d7ac6 commit 97c7c91

File tree

2 files changed

+115
-18
lines changed

2 files changed

+115
-18
lines changed

events/include/events/Event.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@
2020
#include <utility>
2121
#include "events/EventQueue.h"
2222
#include "platform/mbed_assert.h"
23+
#include "platform/mbed_error.h"
2324

2425
namespace events {
2526
/** \defgroup events-public-api Events
2627
* \ingroup mbed-os-public
2728
* @{
2829
*/
2930

31+
static constexpr std::chrono::duration<int, std::milli> non_periodic{-1};
32+
3033
/** Event
3134
*
3235
* Representation of an event for fine-grain dispatch control
@@ -67,7 +70,7 @@ class Event<void(ArgTs...)> {
6770
_event->equeue = &q->_equeue;
6871
_event->id = 0;
6972
_event->delay = duration(0);
70-
_event->period = duration(-1);
73+
_event->period = non_periodic;
7174

7275
_event->post = &Event::event_post<F>;
7376
_event->dtor = &Event::event_dtor<F>;
@@ -139,13 +142,24 @@ class Event<void(ArgTs...)> {
139142

140143
/** Configure the period of an event
141144
*
142-
* @param p Period (in milliseconds) for repeatedly dispatching an event, expressed as a Chrono duration.
145+
* @param p Period (in milliseconds) for repeatedly dispatching an event, expressed as a Chrono
146+
* duration. Period must be either non_periodic or > 0ms. If an invalid period is supplied
147+
* then a default non_periodic value is used.
143148
* E.g. period(200ms)
144149
*/
145150
void period(duration p)
146151
{
147152
if (_event) {
148-
_event->period = p;
153+
if (p > duration(0)) {
154+
_event->period = p;
155+
156+
} else {
157+
if (p != non_periodic) {
158+
MBED_WARNING(MBED_ERROR_INVALID_ARGUMENT,
159+
"Invalid period specified, defaulting to non_periodic.");
160+
}
161+
_event->period = non_periodic;
162+
}
149163
}
150164
}
151165

events/tests/TESTS/events/queue/main.cpp

Lines changed: 98 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,12 @@ void simple_posts_test##i() { \
9393
TEST_ASSERT(touched); \
9494
\
9595
touched = false; \
96-
queue.call_in(1, func##i,##__VA_ARGS__); \
96+
queue.call_in(1ms, func##i,##__VA_ARGS__); \
9797
queue.dispatch(2); \
9898
TEST_ASSERT(touched); \
9999
\
100100
touched = false; \
101-
queue.call_every(1, func##i,##__VA_ARGS__); \
101+
queue.call_every(1ms, func##i,##__VA_ARGS__); \
102102
queue.dispatch(2); \
103103
TEST_ASSERT(touched); \
104104
}
@@ -126,7 +126,7 @@ void call_in_test()
126126

127127
for (int i = 0; i < N; i++) {
128128
tickers[i].start();
129-
queue.call_in((i + 1) * 100, time_func, &tickers[i], (i + 1) * 100);
129+
queue.call_in((i + 1) * 100ms, time_func, &tickers[i], (i + 1) * 100);
130130
}
131131

132132
queue.dispatch(N * 100);
@@ -141,7 +141,7 @@ void call_every_test()
141141

142142
for (int i = 0; i < N; i++) {
143143
tickers[i].start();
144-
queue.call_every((i + 1) * 100, time_func, &tickers[i], (i + 1) * 100);
144+
queue.call_every((i + 1) * 100ms, time_func, &tickers[i], (i + 1) * 100);
145145
}
146146

147147
queue.dispatch(N * 100);
@@ -172,7 +172,7 @@ void cancel_test1()
172172
int ids[N];
173173

174174
for (int i = 0; i < N; i++) {
175-
ids[i] = queue.call_in(1000, no);
175+
ids[i] = queue.call_in(1000ms, no);
176176
}
177177

178178
for (int i = N - 1; i >= 0; i--) {
@@ -308,12 +308,12 @@ void time_left_test()
308308
EventQueue queue(TEST_EQUEUE_SIZE);
309309

310310
// Enque check events
311-
TEST_ASSERT(queue.call_in(50, check_time_left, &queue, 0, 100 - 50));
312-
TEST_ASSERT(queue.call_in(200, check_time_left, &queue, 1, 200 - 200));
311+
TEST_ASSERT(queue.call_in(50ms, check_time_left, &queue, 0, 100 - 50));
312+
TEST_ASSERT(queue.call_in(200ms, check_time_left, &queue, 1, 200 - 200));
313313

314314
// Enque events to be checked
315-
timeleft_events[0] = queue.call_in(100, time_left, &queue, 0);
316-
timeleft_events[1] = queue.call_in(200, time_left, &queue, 1);
315+
timeleft_events[0] = queue.call_in(100ms, time_left, &queue, 0);
316+
timeleft_events[1] = queue.call_in(200ms, time_left, &queue, 1);
317317
TEST_ASSERT(timeleft_events[0]);
318318
TEST_ASSERT(timeleft_events[1]);
319319

@@ -373,18 +373,18 @@ void mixed_dynamic_static_events_queue_test()
373373

374374
EventTest e1_test;
375375
Event<void()> e1 = queue.event(&e1_test, &EventTest::f0);
376-
e1.delay(10);
377-
e1.period(10);
376+
e1.delay(10ms);
377+
e1.period(10ms);
378378
int id1 = e1.post();
379379
TEST_ASSERT_NOT_EQUAL(0, id1);
380380
EventTest e2_test;
381381
Event<void()> e2 = queue.event(&e2_test, &EventTest::f1, 3);
382-
e2.period(10);
382+
e2.period(10ms);
383383
int id2 = e2.post();
384384
TEST_ASSERT_NOT_EQUAL(0, id2);
385385
EventTest e3_test;
386386
Event<void()> e3 = queue.event(&e3_test, &EventTest::f5, 1, 2, 3, 4, 5);
387-
e3.period(10);
387+
e3.period(10ms);
388388
int id3 = e3.post();
389389
TEST_ASSERT_NOT_EQUAL(0, id3);
390390

@@ -508,6 +508,89 @@ void static_events_queue_test()
508508
TEST_ASSERT_EQUAL(15, test4.counter);
509509
}
510510

511+
static EventQueue period_tests_queue;
512+
static long update_counter = 0;
513+
514+
void handler()
515+
{
516+
update_counter ++;
517+
}
518+
519+
void event_period_tests()
520+
{
521+
// Test a non periodic event ie dispatched only once
522+
523+
Event<void()> event1(&period_tests_queue, handler);
524+
525+
event1.delay(10ms);
526+
event1.period(events::non_periodic);
527+
event1.post();
528+
period_tests_queue.dispatch(80);
529+
530+
// Wait 100ms and check the event execution status
531+
wait_us(100 * 1000);
532+
533+
// Event should only have been dispatched once and thus counter
534+
// should be 1
535+
TEST_ASSERT_EQUAL(1, update_counter);
536+
537+
// Test an event with an invalid negative period value.
538+
539+
update_counter = 0;
540+
541+
Event<void()> event2(&period_tests_queue, handler);
542+
543+
event2.delay(10ms);
544+
event2.period(-10ms);
545+
event2.post();
546+
period_tests_queue.dispatch(80);
547+
548+
// Wait 100ms and check the event execution status
549+
wait_us(100 * 1000);
550+
551+
// Event should default to non_periodic and thus only have been
552+
// dispatched once. Counter should be 1.
553+
TEST_ASSERT_EQUAL(1, update_counter);
554+
555+
// Test an event with a zero period.
556+
557+
update_counter = 0;
558+
559+
Event<void()> event3(&period_tests_queue, handler);
560+
561+
event3.delay(10ms);
562+
event3.period(0ms);
563+
event3.post();
564+
period_tests_queue.dispatch(80);
565+
566+
// Wait 100ms and check the event execution status
567+
wait_us(100 * 1000);
568+
569+
// Event should default to non_periodic and thus only have been
570+
// dispatched once. Counter should be 1.
571+
TEST_ASSERT_EQUAL(1, update_counter);
572+
573+
// Test a periodic event ie dispatched a number of times
574+
update_counter = 0;
575+
576+
Event<void()> event4(&period_tests_queue, handler);
577+
578+
event4.delay(10ms);
579+
event4.period(20ms);
580+
event4.post();
581+
period_tests_queue.dispatch(80);
582+
583+
// Wait 100ms and check the event execution status
584+
wait_us(100 * 1000);
585+
586+
// The event should be first dispatched after 10ms and then
587+
// every subsequent 20ms until the dispatcher has completed.
588+
// Thus the counter should be incremented after :
589+
// 10ms, 30ms, 50ms and 70ms
590+
TEST_ASSERT_EQUAL(4, update_counter);
591+
592+
}
593+
511594
// Test setup
512595
utest::v1::status_t test_setup(const size_t number_of_cases)
513596
{
@@ -535,8 +618,8 @@ const Case cases[] = {
535618

536619
Case("Testing time_left", time_left_test),
537620
Case("Testing mixed dynamic & static events queue", mixed_dynamic_static_events_queue_test),
538-
Case("Testing static events queue", static_events_queue_test)
539-
621+
Case("Testing static events queue", static_events_queue_test),
622+
Case("Testing event period values", event_period_tests)
540623
};
541624

542625
Specification specification(test_setup, cases);

0 commit comments

Comments
 (0)