Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elegant way to add/remove descriptors to/from poll

Tags:

c++

c

unix

polling

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?

like image 686
Shamdor Avatar asked Nov 06 '12 09:11

Shamdor


1 Answers

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.

like image 163
Moshe Gottlieb Avatar answered Oct 21 '22 10:10

Moshe Gottlieb