I have two Contiki processes with one process, master
, posting two different events to a second process, send
. The first event sent is PROCESS_EVENT_CONTINUE
and the second event is PROCESS_EVENT_MSG
.
I am posting these events sequentially, one after another, from the process called main
.
The complete code is:
#include "contiki.h"
#include "lib/list.h"
#include "lib/memb.h"
#include "lib/random.h"
#include "net/rime/rime.h"
#include<stdio.h>
PROCESS(master, "master_DGHS");
PROCESS(send, "master_DGHS");
AUTOSTART_PROCESSES( &master, &send);
PROCESS_THREAD(master, ev, data)
{
PROCESS_BEGIN();
process_post(&send, PROCESS_EVENT_CONTINUE, NULL);
process_post(&send, PROCESS_EVENT_MSG, NULL);
PROCESS_END();
}
PROCESS_THREAD(send, ev, data)
{
static struct etimer et;
PROCESS_BEGIN();
while(1)
{
PROCESS_WAIT_EVENT();
if(ev == PROCESS_EVENT_CONTINUE)
{
printf("PROCESS_EVENT_CONTINUE\n");
etimer_set(&et, CLOCK_SECOND );
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
}else
if(ev == PROCESS_EVENT_MSG)
{
printf("PROCESS_EVENT_MSG\n");
etimer_set(&et, CLOCK_SECOND );
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
}
}
PROCESS_END();
}
The problem is that the second process send
sees the first event (it prints PROCESS_EVENT_CONTINUE
), but it doesn't see the second event (it does not print PROCESS_EVENT_MSG
).
In other words, the second event gets lost. However if I remove the source line
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
the second process send
sees both events (both PROCESS_EVENT_CONTINUE
and PROCESS_EVENT_MSG
are printed). So, adding this source line causes the second event, PROCESS_EVENT_MSG
, to be ignored or discarded.
Why does adding this source line result in the second event getting lost?
The problem is that
PROCESS_WAIT_EVENT_UNTIL
consumes all events until the loop's condition becomes true.This is the sequence of actions in your example:
send
process getsPROCESS_EVENT_CONTINUE
event.printf
, sets up a timer, and entersPROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
send
process getsPROCESS_EVENT_MSG
event immediately after.WAIT_EVENT_UNTIL
loop and discards the second event, because the timer is not expired yet.send
process getsPROCESS_EVENT_TIMER
event.So, the second event is received by the process, but not acted upon, since the process is waiting for another event. Hope that now you understand why removing the
WAIT_EVENT_UNTIL
macro solves this issue.