Is it possible to get the number of items that are left in the EventQueue? I'm having an asynchronous processing step in my application using an EventQueue, and I want to terminate the thread when the queue is done processing... I don't see anything on the public C++ API to reference this.
cc @geky
[X] Question
[ ] Enhancement
[ ] Bug
I don't think that there is any function providing that in C++ API. Right now you can do this like this in C API:
#include "mbed.h"
void pass_func(void *eh)
{
}
void any_events(equeue_t q)
{
struct equeue_event *e = q.queue;
if(e)
{
printf("some events left\n\r");
} else
{
printf("no more events left\n\r");
}
}
int how_many_events(equeue_t q)
{
struct equeue_event *e = q.queue;
int i = 0;
for (; e; e = e->next) {
for (struct equeue_event *s = e; s; s = s->sibling) {
i++;
}
}
return i;
}
int main() {
equeue_t q;
int err = equeue_create(&q, 1024);
int id0 = equeue_call_in(&q, 1, pass_func, 0);
int id1 = equeue_call_in(&q, 100, pass_func, 0);
int id2 = equeue_call_in(&q, 100, pass_func, 0);
int id3 = equeue_call_in(&q, 100, pass_func, 0);
any_events(q);
printf("there are %d events left\n\r", how_many_events(q));
equeue_dispatch(&q, 50);
any_events(q);
equeue_dispatch(&q, 100);
any_events(q);
equeue_destroy(&q);
}
I think it would be a good idea to implement a function to do this in C++.
What do you think @jamesbeyond @maciejbocianski ?
@Tharazi97 that example is using the equeue struct invasively. The structure may change even on patch releases which could cause your code to break.
There's currently no way to do this in the C API.
I was looking into what a stat interface in equeue would look like for debugging purposes:
struct equeue_stats {
size_t unused_bytes; // bytes never touched
size_t used_bytes; // bytes touched and reserved for specific allocation size
size_t active_bytes; // bytes in use by pending events
};
Though I'm not sure that makes sense for checking if a thread can be safely terminated. You're looking looking to do some sort of thread join but on an event queue right? How would you prevent a thread from putting more events on your event queue in the slice of time between checking if the event queue is empty?
Actually, you may be able to get what you want with current event queue by jacking the equeue_background function:
void copy_equeue_timer(void *p, int m;) {
*(int*)p = ms;
}
void my_thread(void*) {
// equeue_background sets ms to the time until next event,
// 0 if events are immediately pending, or -1 if no events are pending
volatile int ms = 0;
equeue_background(&q, copy_equeue_timer, &ms);
while (ms >= 0) {
// NOTE, this can leave us waiting unnecessarily if events are cancelled.
// Alternatively you can use a timeout of 0, but this would effectively be polling.
equeue_dispatch(&q, ms);
}
}
This also exists in the C++ API, though may need to be tweaked slightly:
https://os.mbed.com/docs/mbed-os/v5.13/mbed-os-api-doxy/classevents_1_1_event_queue.html#abc2f99a102e2ef44a83d037b3662c27c
Thanks @geky, will take a look.
Though I'm not sure that makes sense for checking if a thread can be safely terminated. You're looking looking to do some sort of thread join but on an event queue right? How would you prevent a thread from putting more events on your event queue in the slice of time between checking if the event queue is empty?
I am in full control over both the thread and which events get pushed. So I know when I've stopped pushing events.
Event if not queuing more, checking how many events are pending is racy - the event is removed from the queue before it starts running, so the count reaches zero on entry to your last event.
You presumably want to wait for all your events to finish running.
This is somewhat related to #10750, where we want to force cancellation of pending and wait for any already-started to finish. Discussion there about ordering is relevant.
Generally, asking for characteristics of the queue itself seems like a dubious approach as it locks in the assumption that it's a private queue - you may well want to be sharing a queue with others. I'd be inclined to just have your own personal "queued events" counter that you increment when queuing, and decrement in your event handler.
@janjongboom were your questions answered, can this be closed?
@0xc0170 I'd still want this in the C++ API, but not sure if that will happen based on @kjbracey-arm's comments. If this won't be added then it can be closed.
I may have failed to grasp your use case - I think a count would be fine for your use, if your use is "check number of queued events from the event dispatching thread itself". That would reliably return 0 inside the last event handler.
I was thinking you might be trying to do it from another thread, which would enter the same racey world of pain you get for event_cancel, but if used in the event queue itself, or the same thread, then it seems reasonable.
Performing a full count might be a bit heavy, if somehow there were a lot of events - maybe you'd want a more streamlined "empty" call returning bool.
Thank you for raising this issue. Please note we have updated our policies and
now only defects should be raised directly in GitHub. Going forward questions and
enhancements will be considered in our forums, https://forums.mbed.com/ . If this
issue is still relevant please re-raise it there.
This GitHub issue will now be closed.
Most helpful comment
Actually, you may be able to get what you want with current event queue by jacking the
equeue_backgroundfunction:This also exists in the C++ API, though may need to be tweaked slightly:
https://os.mbed.com/docs/mbed-os/v5.13/mbed-os-api-doxy/classevents_1_1_event_queue.html#abc2f99a102e2ef44a83d037b3662c27c