Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   Related Pages   Examples  

poller_kqueue.cc

00001 /************************************************************************
00002  *
00003  * $Id: poller_kqueue.cc,v 1.13 2002/10/16 19:36:38 crooney Exp $
00004  *
00005  ***********************************************************************/
00006 
00007 /**************************************************************************
00008 Copyright 2001, Christopher Rooney crooney@crooney.com
00009 
00010 This file is part of fpoller.
00011 
00012 fpoller is free software; you can redistribute it and/or modify
00013 it under the terms of the GNU General Public License as published by
00014 the Free Software Foundation; either version 2 of the License, or
00015 (at your option) any later version.
00016 
00017 fpoller is distributed in the hope that it will be useful,
00018 but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 GNU General Public License for more details.
00021 
00022 You should have received a copy of the GNU General Public License
00023 along with fpoller; if not, write to the Free Software
00024 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 *************************************************************************/
00026 
00027 #include <string.h>
00028 #include <sys/ioctl.h>
00029 #include <sys/stat.h>
00030 #include <sys/types.h>
00031 #include <sys/time.h>
00032 #include <sys/event.h>
00033 #include <fcntl.h>
00034 #include <sys/poll.h>
00035 #include <errno.h>
00036 
00037 #include "poller_kqueue.h"
00038 
00039 namespace fpoller {
00040   
00041   void poller_kqueue::add(int fd, short interest, callback *cb){
00042     if (cb->operator()(fd) == REMOVE) {
00043       //we can just avoid adding;
00044       delete cb;
00045       return;
00046     }
00047     struct kevent k;
00048     EV_SET(&k,fd,poll_to_kq(interest),EV_ADD,0,0,0);
00049     change_queue_.push_back(k);
00050     fd_maps_.get_map(interest).insert(std::make_pair(fd,callback_wrapper(cb)));
00051   }
00052 
00053   void poller_kqueue::remove(int fd, short interest){
00054     fd_map &map = fd_maps_.get_map(interest);
00055     fd_map::iterator it = map.find(fd);
00056     if (it != map.end()){
00057       struct kevent k;
00058       EV_SET(&k,fd,poll_to_kq(interest),EV_DELETE,0,0,0);
00059       map.erase(it);
00060       change_queue_.push_back(k);
00061     }
00062   }
00063 
00064   int poller_kqueue::poll(int timeout){
00065     timespec ts;
00066     ts.tv_sec = timeout / 1000;
00067     ts.tv_nsec = (timeout % 1000) * 1000;
00068     int nready,retval;
00069     if (poll_queue_.size() < (fd_maps_.size()+(change_queue_.size()))){
00070       // after call to remove, we need room for an error report for 
00071       // the EV_DELETE, but fd is not in fd_map_ 
00072       poll_queue_.resize(fd_maps_.size()+(change_queue_.size()));
00073     }
00074     if ((retval = nready = ::kevent(kq_fd_,&change_queue_[0],change_queue_.size(),
00075                                   &poll_queue_[0],poll_queue_.size(),&ts)) > -1){
00076       change_queue_.clear();
00077       for (struct kevent *ke = &poll_queue_[0]; nready ; ke++){
00078         nready--;
00079         short interest = kq_to_poll(ke->filter);        
00080         fd_map &map = fd_maps_.get_map(interest);       
00081         fd_map::iterator it = map.find(ke->ident);
00082         if (it == map.end()){
00083           //should never happen
00084           remove(ke->ident,interest);
00085         }else{
00086           if ((*(it->second))(ke->ident) == REMOVE){
00087             remove(ke->ident,interest);
00088           }
00089         }
00090       }
00091     }
00092     return retval;
00093   }
00094 }//namespace
00095 
00096 
00097 
00098 
00099 
00100 

Generated at Wed Oct 16 16:02:39 2002 for fpoller by doxygen1.2.9.1 written by Dimitri van Heesch, © 1997-2001