arobenko / embxx

embxx - Embedded C++ Library
GNU General Public License v3.0
262 stars 35 forks source link

EventLoop - runOnce #17

Open akowalew opened 6 years ago

akowalew commented 6 years ago

Hi!

In my embedded application, which is based mainly on your EventLoop, I have to use 3rd party library. This library is written in pure C and needs to be polled from main loop cyclically:

while(1)
{
   ...
   library_runOnce();
   ...
}

There is a need to extend EventLoop, by adding something like runOnce(). It will be similar to the Boost::Asio's io_service::run_one() or ROS's ros::spinOnce(). It has to execute only one event and return back to the caller. I have implemented this, by adding to the EventLoop code like this:

template <std::size_t TSize,
          typename TLock,
          typename TCond>
void EventLoop<TSize, TLock, TCond>::runOnce()
{
    lock_.lock();
    auto lockGuard = embxx::util::makeScopeGuard(
        [this]()
        {
            lock_.unlock();
        });

    volatile bool empty = queue_.isEmpty();
    if (empty) {
        return;
    }

    auto taskPtr = reinterpret_cast<Task*>(&queue_.front());
    auto sizeToRemove = taskPtr->getSize();
    lock_.unlock();
    taskPtr->exec();
    taskPtr->~Task();
    lock_.lock();
    queue_.popFront(sizeToRemove);
}

It has of course one serious disadvantage: it is not invoking cond_.wait(lock_);, but it allows now to use EventLoop with 3rd party libraries:

while(1)
{
   library_runOnce();
   _evenLoop.runOnce();
}

I think it would be nice to have this feature in embxx.

arobenko commented 6 years ago

OK, thanks. I'll consider adding something like this in the future. As I have mentioned already in other tickets, I don't have much time to spend on this project and I don't think I will come around to doing something here until May or event later.