> this is likely going to be slow Yeah, but performance is not a concern for my use case.
> you could simply push them onto a vector and clear it out in check. I've tried to replace std::map with std::vector, but this didn't help. Actually, I used std::list instead of std::vector, because ev::io has a private copy constructor, but we might need to resize a vector and move I/O watchers. I ended up with the following code: for (auto &io : ctx.ios) { if (io.watcher.is_pending()) { auto poll_fd = std::find_if( ctx.poll_fds.begin(), ctx.poll_fds.end(), [&](Glib::PollFD &poll) { return poll.get_fd() == io.watcher.fd; }); if (poll_fd != ctx.poll_fds.end()) { poll_fd->set_revents( to_glib_events(ev_clear_pending(ctx.loop.raw_loop, &io.watcher))); } } } ctx.ios.clear(); By the way, it turned out that C-language implementation from EV::Glib behaves in the same way: also hangs. It worth to mention, that I've tried to create ev::idle to prevent the event loop from sleeping. This solves the problem with hanging, but the busy loop loads CPU for 100%. > You could also try forcing libev to use select or poll as backend I will try to use select or poll as a backend. Thanks for the idea. On Wed, Jul 7, 2021 at 3:21 AM Marc Lehmann <schm...@schmorp.de> wrote: > On Wed, Jul 07, 2021 at 12:06:37AM +0200, Oleksandr Kozlov < > aleks.a.koz...@gmail.com> wrote: > > from the EV::Glib Perl module [3]. > > Note that this is likely going to be slow, as glib does not have the > necessary hooks to efficiently be embedded into another event loop. > > > ctx.poll_fds.clear(); > > int timeout = 0; > > ctx.context->query(ctx.priority, timeout, ctx.poll_fds); > > for (Glib::PollFD &poll_fd : ctx.poll_fds) { > > int fd = poll_fd.get_fd(); > > ctx.ios.try_emplace(fd, fd, to_ev_events(poll_fd.get_events())); > > This looks as if you cache io watchers by fd, and could be the reason for > the problem - Glib doesn't tell you when the fd changes, so the fd is not > a unique enough primary key for your map (which really should be an array, > too). > > What EV::Glib is doing is create I/O watchers in a prepare call and stop > them in the check call - you could simply push them onto a vector and clear > it out in check. > > You could also try forcing libev to use select or poll as backend, which, > if Glib uses a lot of watchers, is likely more efficient, and this is a > quick way of checking whether this is your real problem - note that using > these backends for these side effects is not really supported by libev, > so you should definitely fix the c++ side, possibly followed by using > select/poll for efficiency. > > -- > The choice of a Deliantra, the free code+content > MORPG > -----==- _GNU_ http://www.deliantra.net > ----==-- _ generation > ---==---(_)__ __ ____ __ Marc Lehmann > --==---/ / _ \/ // /\ \/ / schm...@schmorp.de > -=====/_/_//_/\_,_/ /_/\_\ >
_______________________________________________ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/mailman/listinfo/libev