Add selector implement

This commit is contained in:
Kirigaya Kazuto 2018-05-29 13:36:38 +08:00
parent ebaa51c8f5
commit a5e1ec5560
2 changed files with 121 additions and 2 deletions

109
gsock.cpp
View File

@ -39,6 +39,7 @@ using BYTE = unsigned char;
#include <cstring> /// memset #include <cstring> /// memset
#include <string> #include <string>
#include <stdexcept> #include <stdexcept>
#include <vector>
class _init_winsock2_2_class class _init_winsock2_2_class
{ {
@ -429,6 +430,111 @@ int udpsock::recv(void* buffer,int bufferLength)
return ::recv(_vp->sfd,(char*)buffer,bufferLength,0); 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) int DNSResolve(const std::string& HostName, std::string& _out_IPStr)
{ {
/// Use getaddrinfo instead /// Use getaddrinfo instead
@ -464,4 +570,5 @@ int DNSResolve(const std::string& HostName, std::string& _out_IPStr)
/// Undefine marcos /// Undefine marcos
#undef myliblog #undef myliblog

14
gsock.h
View File

@ -23,6 +23,8 @@ protected:
struct _impl; struct _impl;
_impl* _vp; _impl* _vp;
friend class selector;
}; };
class sock : public vsock class sock : public vsock
@ -118,11 +120,21 @@ class selector
{ {
public: public:
selector(); selector();
~selector();
void clear(); void clear();
void add_read(const vsock&); void add_read(const vsock&);
void add_write(const vsock&); void add_write(const vsock&);
void add_error(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: private:
struct _impl; struct _impl;
_impl* _pp; _impl* _pp;