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 #ifndef POLLER_UTIL_H
00028 #define POLLER_UTIL_H
00029 #include <sys/errno.h>
00030 #include <sys/types.h>
00031 #include <sys/socket.h>
00032 #include <unistd.h>
00033 #include <poll.h>
00034 #include <sys/time.h>
00035 #include <fcntl.h>
00036 #include <netdb.h>
00037 #include <netinet/in.h>
00038 #include <exception>
00039 #include <functional>
00040 #include <string.h>
00041
00042
00043
00044 #ifndef ECONNABORTED
00045 #define ECONNABORTED EWOULDBLOCK
00046 #endif
00047 #ifndef EPROTO
00048 #define EPROTO EWOULDBLOCK
00049 #endif
00050 #ifndef EINTR
00051 #define EINTR EWOULDBLOCK
00052 #endif
00053
00054 #ifndef MAX_FDS
00055 # define MAX_FDS 16384
00056 #endif
00057
00058 namespace fpoller{
00060 const short READ = POLLIN;
00062 const short WRITE = POLLOUT;
00063 const short ERROR = POLLERR | POLLHUP | POLLNVAL;
00064
00066 enum ret_val {KEEP, REMOVE};
00067
00070 int get_listen_socket(int port, int backlog = 2048);
00071
00074 void set_non_blocking(int fd);
00075
00078 struct callback : public std::unary_function<int,int> {
00081 virtual ret_val operator()(int fd)=0;
00083 virtual ~callback(){};
00084 };
00085
00090 struct callback_ptr{
00091 callback *pcb_;
00092 int *count_;
00093 callback_ptr():pcb_(NULL),count_(new int(1)){}
00094 explicit callback_ptr(callback *pcb):pcb_(pcb),count_(new int(1)){}
00095 callback_ptr(const callback_ptr &rhs):pcb_(rhs.pcb_),count_(rhs.count_){++(*count_);}
00096 inline callback_ptr &operator=(const callback_ptr &rhs){
00097 if (--(*count_) < 1){
00098 delete count_;
00099 delete pcb_;
00100 }
00101 pcb_= rhs.pcb_;
00102 count_ = rhs.count_;
00103 ++(*count_);
00104 return *this;
00105 }
00106 ~callback_ptr(){
00107 if (--(*count_) < 1){
00108 delete count_;
00109 delete pcb_;
00110 }
00111 }
00112 inline callback &operator*(){return *pcb_;}
00113 inline callback *operator->(){return pcb_;}
00114 inline callback *ptr(){return pcb_;}
00115 inline int use_count(){return *count_;}
00116 };
00117
00119 struct callback_wrapper {
00120 callback_ptr cb_;
00121 int operator()(int fd);
00122 callback_wrapper(callback *cb):cb_(cb){}
00123 callback_wrapper(const callback_wrapper &rhs):cb_(rhs.cb_){}
00124 callback_wrapper():cb_(NULL){}
00125 inline callback_wrapper &operator=(const callback_wrapper &rhs){cb_ = rhs.cb_; return *this;}
00126 inline callback &operator*(){return *cb_;}
00127 inline callback *operator->(){return cb_.operator->();}
00128 };
00129
00132 class exception : public std::exception {
00133 const char *where_, *what_;
00134 int errnum_;
00135 public:
00138 exception(const char *where, const char *what):where_(where),what_(what),errnum_(0){}
00141 exception(const char *where, int errnum):where_(where),what_(NULL),errnum_(errnum){}
00143 inline const char *what() const throw (){return what_ ? what_ : strerror(errnum_);}
00145 inline const char *where() const {return where_;}
00147 inline int which() const {return errnum_;}
00148 };
00149
00152 inline bool would_block(int err){
00153 return err == EWOULDBLOCK ||
00154 err == ECONNABORTED ||
00155 err == EPROTO ||
00156 err == EINTR ;
00157 }
00158
00159 }
00160
00161 #endif
00162
00163
00164
00165
00166