00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "poller_generic.h"
00028
00029 namespace fpoller {
00030 poller_generic::poller_generic():num_fds_(0),pollfds_(MAX_FDS){
00031 for (int i = 0; i<MAX_FDS; i++){
00032 available_.push(i);
00033 pollfds_[i].fd = -1;
00034 }
00035 }
00036
00037 void poller_generic::add(int fd, short interest, callback* cb){
00038 if (cb->operator()(fd) == REMOVE) {
00039
00040 delete cb;
00041 return;
00042 }
00043 if (available_.empty()){
00044 unsigned i = pollfds_.size();
00045 pollfds_.resize(static_cast<unsigned>(i*1.5));
00046 for (;i < pollfds_.size();i++){
00047 available_.push(i);
00048 pollfds_[i].fd = -1;
00049 }
00050 }else{
00051 fd_map::iterator iter = fd_map_.find(fd);
00052 if (iter != fd_map_.end()){
00053 fd_info &info = iter->second;
00054 pollfds_[info.pollfds_index].fd = fd;
00055 pollfds_[info.pollfds_index].events |= interest;
00056 if ((interest & READ)){
00057 info.reader = callback_wrapper(cb);
00058 }
00059 if ((interest & WRITE)){
00060 info.writer = callback_wrapper(cb);
00061 }
00062 }else{
00063 int index = available_.top();
00064 available_.pop();
00065 pollfds_[index].fd = fd;
00066 pollfds_[index].events = interest;
00067 fd_info info;
00068 info.pollfds_index = index;
00069 if (interest & READ){
00070 info.reader = callback_wrapper(cb);
00071 }
00072 if (interest & WRITE){
00073 info.writer = callback_wrapper(cb);
00074 }
00075 fd_map_.insert(std::make_pair(fd,info));
00076 if (index > num_fds_){
00077 num_fds_ = index;
00078 }
00079 }
00080 }
00081 }
00082
00083 void poller_generic::remove(int fd, short interest){
00084 fd_map::iterator iter = fd_map_.find(fd);
00085 if (iter != fd_map_.end()){
00086 fd_info &info = iter->second;
00087 int &index = info.pollfds_index;
00088 pollfd &pfd = pollfds_[index];
00089 if (interest ^ pfd.events > 0){
00090
00091 pfd.events ^= interest;
00092 if (interest & READ){
00093 info.reader = callback_wrapper();
00094 }
00095 if (interest & WRITE){
00096 info.writer = callback_wrapper();
00097 }
00098 }else{
00099
00100 pfd.fd = -1;
00101 pfd.events = 0;
00102 pfd.revents = 0;
00103 available_.push(index);
00104 if (index >= num_fds_){
00105 for(;pollfds_[num_fds_].fd <0 && num_fds_;){
00106 num_fds_--;
00107 }
00108 }
00109 fd_map_.erase(iter);
00110 }
00111 }
00112 }
00113
00114 int poller_generic::poll(int timeout){
00115 int nready,retval;
00116 if ((retval = nready = ::poll(&pollfds_[0],num_fds_+1,timeout)) < 0){
00117 return retval;
00118 }
00119
00120 for (pollfd *pfd = &pollfds_[0];
00121 nready && (pfd < (&pollfds_[num_fds_ + 1])) ;
00122 pfd++){
00123 short relevant_events;
00124 if ((relevant_events = pfd->revents & (pfd->events | ERROR))){
00125 nready--;
00126 fd_info &info = fd_map_[pfd->fd];
00127 if (relevant_events & (READ | ERROR)) {
00128 try_callback(pfd->fd,info.reader,READ);
00129 }
00130 if (relevant_events & (WRITE | ERROR)) {
00131 try_callback(pfd->fd,info.writer,WRITE);
00132 }
00133 }
00134 }
00135 return retval;
00136 }
00137
00138 }
00139
00140
00141