a) kqueue delegate's remove()
...
vector <struct kevent> poll_queue_,change_queue_;
typedef std::hash_map<int, callback_wrapper> fd_map;
struct fd_maps {
fd_map reader,writer;
inline int size(){return reader.size()+writer.size();}
inline fd_map &get_map(short interest){
return (interest & WRITE) ? writer : reader;
}
};
fd_maps fd_maps_;
...
void poller_kqueue::remove(int fd, short interest){
fd_map &map = fd_maps_.get_map(interest);
fd_map::iterator it = map.find(fd);
if (it != map.end()){
struct kevent k;
EV_SET(&k,fd,poll_to_kq(interest),EV_DELETE,0,0,0);
map.erase(it);
change_queue_.push_back(k);
}
}
b) traditional poll() delegate's remove()
...
struct fd_info {
callback_wrapper reader,writer;
int pollfds_index;
};
typedef std::hash_map<int,fd_info> fd_map;
fd_map fd_map_;
...
void poller_generic::remove(int fd, short interest){
fd_map::iterator iter = fd_map_.find(fd);
if (iter != fd_map_.end()){
fd_info &info = iter->second;
int &index = info.pollfds_index;
pollfd &pfd = pollfds_[index];
if (interest ^ pfd.events > 0){
//the fd waits on other events just disable interest
pfd.events ^= interest;
if (interest & READ){
info.reader = callback_wrapper();
}
if (interest & WRITE){
info.writer = callback_wrapper();
}
}else{
//actually remove
pfd.fd = -1;
pfd.events = 0;
pfd.revents = 0;
available_.push(index);
if (index >= num_fds_){
for(;pollfds_[num_fds_].fd <0 && num_fds_;){
num_fds_--;
}
}
fd_map_.erase(iter);
}
}
}
End of Listing