From a5e1ec556086b04b7f4a77d6addae3e912f47f7c Mon Sep 17 00:00:00 2001 From: Kiritow <1362050620@qq.com> Date: Tue, 29 May 2018 13:36:38 +0800 Subject: [PATCH] Add selector implement --- gsock.cpp | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++- gsock.h | 14 ++++++- 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/gsock.cpp b/gsock.cpp index 718d7b3..51a918c 100644 --- a/gsock.cpp +++ b/gsock.cpp @@ -39,6 +39,7 @@ using BYTE = unsigned char; #include /// memset #include #include +#include class _init_winsock2_2_class { @@ -429,6 +430,111 @@ int udpsock::recv(void* buffer,int bufferLength) return ::recv(_vp->sfd,(char*)buffer,bufferLength,0); } +// Select +struct selector::_impl +{ + fd_set readset, writeset, errorset; + int readsz, writesz, errorsz; +}; + +selector::selector() : _pp(new _impl) +{ + clear(); +} + +selector::~selector() +{ + if (_pp) + { + delete _pp; + _pp = nullptr; + } +} + +void selector::clear() +{ + FD_ZERO(&_pp->readset); + FD_ZERO(&_pp->writeset); + FD_ZERO(&_pp->errorset); + _pp->readsz = _pp->writesz = _pp->errorsz = 0; +} + +void selector::add_read(const vsock& v) +{ + if (v._vp->created) + { + FD_SET(v._vp->sfd, &_pp->readset); + ++_pp->readsz; + } +} + +void selector::add_write(const vsock& v) +{ + if (v._vp->created) + { + FD_SET(v._vp->sfd, &_pp->writeset); + ++_pp->writesz; + } +} + +void selector::add_error(const vsock& v) +{ + if (v._vp->created) + { + FD_SET(v._vp->sfd, &_pp->errorset); + ++_pp->errorsz; + } +} + +int selector::wait_for(int second, int ms) +{ + fd_set* pread = (_pp->readsz) ? (&_pp->readset) : NULL; + fd_set* pwrite = (_pp->writesz) ? (&_pp->writeset) : NULL; + fd_set* perr = (_pp->errorsz) ? (&_pp->errorset) : NULL; + + if (!(pread || pwrite || perr)) + { + return 0; + } + + struct timeval tval; + tval.tv_sec = second; + tval.tv_usec = ms; + + int ndfs = 0; + return ::select(ndfs, pread, pwrite, perr, &tval); +} + +int selector::wait() +{ + fd_set* pread = (_pp->readsz) ? (&_pp->readset) : NULL; + fd_set* pwrite = (_pp->writesz) ? (&_pp->writeset) : NULL; + fd_set* perr = (_pp->errorsz) ? (&_pp->errorset) : NULL; + + if (!(pread || pwrite || perr)) + { + return 0; + } + + int ndfs = 0; + return ::select(ndfs, pread, pwrite, perr, NULL); +} + +bool selector::can_read(const vsock& v) +{ + return FD_ISSET(v._vp->sfd, &_pp->readset); +} + +bool selector::can_write(const vsock& v) +{ + return FD_ISSET(v._vp->sfd, &_pp->writeset); +} + +bool selector::is_error(const vsock& v) +{ + return FD_ISSET(v._vp->sfd, &_pp->errorset); +} + int DNSResolve(const std::string& HostName, std::string& _out_IPStr) { /// Use getaddrinfo instead @@ -464,4 +570,5 @@ int DNSResolve(const std::string& HostName, std::string& _out_IPStr) /// Undefine marcos -#undef myliblog \ No newline at end of file +#undef myliblog + diff --git a/gsock.h b/gsock.h index 52c2a50..7f6d671 100644 --- a/gsock.h +++ b/gsock.h @@ -23,6 +23,8 @@ protected: struct _impl; _impl* _vp; + + friend class selector; }; class sock : public vsock @@ -118,11 +120,21 @@ class selector { public: selector(); + ~selector(); + void clear(); + void add_read(const vsock&); void add_write(const vsock&); void add_error(const vsock&); - int select(int); + + int wait_for(int second, int ms = 0); + int wait(); + + bool can_read(const vsock&); + bool can_write(const vsock&); + bool is_error(const vsock&); + private: struct _impl; _impl* _pp;