Elegant way to add/remove descriptors to/from poll
Asked Answered
T

1

7

I have to handle around 1000 descriptors in one poll (I can't use epoll as it's Linux specific) and I have to be able to dynamically add/remove them(handle new connections and remove closed).

This means I should recombine the descriptors array on each iteration.

This is rather obvious from a technical point of view, but does anybody know a beautiful way to do that?

Thornhill answered 6/11, 2012 at 9:53 Comment(0)
C
5

I'd keep the dead descriptors in the array, and purge once in a while. I'd also maintain the location of each descriptor, for easy removal, but this can be optimized further. The trick is to keep invalid descriptors in the array instead of rearranging the array every time.

For instance:

struct pollfd pfds[MY_MAX_FDS];
int nfds = 0;
enum { INVALID_FD = -1 };
....

typedef std::map<int,int> desc_to_index_t;
desc_to_index_t d2i;
....
// add descriptor
if (nfds == MY_MAX_FDS){
    // purge old fds
    // go through pfds and remove everything that has invalid fd
    // pfds should point to a condensed array of valid objects and nfds should be updated as well, as long as d2i.
}
pfds[nfds] = { desc, events, revents};
d2i.insert(std::make_pair(desc,nfds));
++nfds;
....
// remove descriptor
desc_to_index_t::iterator it = d2i.find(desc);
assert(it != d2i.end());
pfds[it->second] = { INVALID_FD, 0, 0 };
d2i.erase(it);

This way you only need to purge once a certain threshold is crossed, and you don't need to build the array every time.

Chemisorb answered 6/11, 2012 at 12:22 Comment(2)
+1 This is probably the best you can really do, other than using epoll. Of course you could still just remove descriptors one by one, since they're just an array in your program's address space, and they're re-uploaded every time anyway, but meh... Note that although epoll is Linux specific, kqueue exists whereever epoll doesn't. With a small abstraction layer (different syscalls, slightly different semantics) it should be possible to use both. Wait, did someone say "libevent"?Decedent
@iMoses just flipping the sign instead of using -1 might give the possibility to temporarily disable polling on a descriptor.Resolution

© 2022 - 2024 — McMap. All rights reserved.