mirror of
https://github.com/Kiritow/GSock.git
synced 2024-03-22 13:10:51 +08:00
Support non-blocking accept()
This commit is contained in:
parent
0213119ad8
commit
014e216301
132
gsock.cpp
132
gsock.cpp
|
@ -372,7 +372,7 @@ struct NBConnectResult::_impl
|
|||
// 3: finished, failed.
|
||||
int status;
|
||||
|
||||
int errcode;
|
||||
gerrno errcode;
|
||||
|
||||
void update();
|
||||
};
|
||||
|
@ -429,12 +429,12 @@ bool NBConnectResult::isFinished()
|
|||
return (_p->status > 1);
|
||||
}
|
||||
|
||||
bool NBConnectResult::isConnected()
|
||||
bool NBConnectResult::isSuccess()
|
||||
{
|
||||
return (_p->status == 2);
|
||||
}
|
||||
|
||||
int NBConnectResult::getErrCode()
|
||||
gerrno NBConnectResult::getErrCode()
|
||||
{
|
||||
return _p->errcode;
|
||||
}
|
||||
|
@ -650,7 +650,7 @@ NBConnectResult sock::connect_nb(const std::string& IPStr, int Port)
|
|||
{
|
||||
// Failed.
|
||||
res._p->status = 3;
|
||||
res._p->errcode = GSOCK_INVALID_IP;
|
||||
res._p->errcode = (gerrno)GSOCK_INVALID_IP;
|
||||
return res;
|
||||
}
|
||||
res._p->saddr6.sin6_port = htons(Port);
|
||||
|
@ -668,7 +668,7 @@ NBConnectResult sock::connect_nb(const std::string& IPStr, int Port)
|
|||
{
|
||||
// Failed.
|
||||
res._p->status = 3;
|
||||
res._p->errcode = GSOCK_INVALID_IP;
|
||||
res._p->errcode = (gerrno)GSOCK_INVALID_IP;
|
||||
return res;
|
||||
}
|
||||
res._p->saddr.sin_port = htons(Port);
|
||||
|
@ -687,11 +687,11 @@ NBConnectResult sock::connect_nb(const std::string& IPStr, int Port)
|
|||
{
|
||||
res._p->status = 1;
|
||||
}
|
||||
else
|
||||
else // xret is a GSock error
|
||||
{
|
||||
// Failed
|
||||
res._p->status = 3;
|
||||
res._p->errcode = xret;
|
||||
res._p->errcode = (gerrno)xret;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -1000,6 +1000,93 @@ int serversock::listen(int MaxCount)
|
|||
return ::listen(_vp->sfd,MaxCount);
|
||||
}
|
||||
|
||||
struct NBAcceptResult::_impl
|
||||
{
|
||||
int sfd;
|
||||
|
||||
// For client use
|
||||
bool isv4;
|
||||
sockaddr_in saddr;
|
||||
sockaddr_in6 saddr6;
|
||||
socklen_t saddrsz;
|
||||
|
||||
sock* out_binding;
|
||||
int* out_binding_sfd;
|
||||
bool* out_binding_created;
|
||||
|
||||
// 0 Not started.
|
||||
// 1 Accepting
|
||||
// 2 Accept success.
|
||||
// 3 Accept failed.
|
||||
int status;
|
||||
gerrno errcode;
|
||||
|
||||
void update();
|
||||
};
|
||||
|
||||
void NBAcceptResult::_impl::update()
|
||||
{
|
||||
if (status > 1) return;
|
||||
|
||||
int ret;
|
||||
if (isv4)
|
||||
{
|
||||
ret = accept(sfd, (sockaddr*)&saddr, &saddrsz);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = accept(sfd, (sockaddr*)&saddr6, &saddrsz);
|
||||
}
|
||||
|
||||
if (ret >= 0)
|
||||
{
|
||||
*out_binding_sfd = sfd;
|
||||
*out_binding_created = true;
|
||||
status = 2;
|
||||
}
|
||||
else // ret == -1
|
||||
{
|
||||
gerrno err = TranslateNativeErrToGErr(GetNativeErrCode());
|
||||
errcode = err;
|
||||
if (err == gerrno::InProgress || err == gerrno::WouldBlock || err == gerrno::Already)
|
||||
{
|
||||
status = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = 3;
|
||||
}
|
||||
}
|
||||
|
||||
myliblog("NBAcceptResult status updated to %d\n", status);
|
||||
}
|
||||
|
||||
NBAcceptResult::NBAcceptResult() : _sp(new _impl)
|
||||
{
|
||||
_sp->status = 0;
|
||||
}
|
||||
|
||||
bool NBAcceptResult::isFinished()
|
||||
{
|
||||
_sp->update();
|
||||
return (_sp->status > 1);
|
||||
}
|
||||
|
||||
bool NBAcceptResult::isSuccess()
|
||||
{
|
||||
return (_sp->status == 2);
|
||||
}
|
||||
|
||||
sock& NBAcceptResult::get()
|
||||
{
|
||||
return *(_sp->out_binding);
|
||||
}
|
||||
|
||||
gerrno NBAcceptResult::getErrCode()
|
||||
{
|
||||
return _sp->errcode;
|
||||
}
|
||||
|
||||
int serversock::accept(sock& _out_s)
|
||||
{
|
||||
if( (!_vp->created) || (_out_s._vp->created) )
|
||||
|
@ -1043,6 +1130,37 @@ int serversock::accept(sock& _out_s)
|
|||
}
|
||||
}
|
||||
|
||||
NBAcceptResult serversock::accept_nb(sock& _out_s)
|
||||
{
|
||||
NBAcceptResult res;
|
||||
if ((!_vp->created) || (_out_s._vp->created))
|
||||
{
|
||||
/// _out_s has been connected.
|
||||
res._sp->status = 3;
|
||||
res._sp->errcode = (gerrno)GSOCK_INVALID_SOCKET;
|
||||
return res;
|
||||
}
|
||||
|
||||
res._sp->sfd = _vp->sfd;
|
||||
res._sp->out_binding = &_out_s;
|
||||
res._sp->out_binding_sfd = &(_out_s._vp->sfd);
|
||||
res._sp->out_binding_created = &(_out_s._vp->created);
|
||||
if (_pp->protocol == AF_INET)
|
||||
{
|
||||
res._sp->isv4 = true;
|
||||
res._sp->saddrsz = sizeof(res._sp->saddr);
|
||||
res._sp->update();
|
||||
}
|
||||
else
|
||||
{
|
||||
res._sp->isv4 = false;
|
||||
res._sp->saddrsz = sizeof(res._sp->saddr6);
|
||||
res._sp->update();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct udpsock::_impl
|
||||
{
|
||||
int protocol;
|
||||
|
|
30
gsock.h
30
gsock.h
|
@ -29,11 +29,11 @@ enum
|
|||
};
|
||||
|
||||
// Internal Socket Call Errcode
|
||||
// Values of all errors are positive number.
|
||||
enum gerrno
|
||||
{
|
||||
UnknownError = -1,
|
||||
OK = 0,
|
||||
// Values of all known errors are positive number.
|
||||
UnknownError,
|
||||
WouldBlock,
|
||||
InProgress,
|
||||
Already,
|
||||
|
@ -78,9 +78,9 @@ public:
|
|||
bool isFinished();
|
||||
// Wait until the connection is finished. (via while loop)
|
||||
void wait();
|
||||
bool isConnected();
|
||||
bool isSuccess();
|
||||
// ErrCode is only usable when the connection is finished and failed.
|
||||
int getErrCode();
|
||||
gerrno getErrCode();
|
||||
private:
|
||||
struct _impl;
|
||||
std::shared_ptr<_impl> _p;
|
||||
|
@ -179,6 +179,24 @@ private:
|
|||
struct _impl;
|
||||
};
|
||||
|
||||
class NBAcceptResult
|
||||
{
|
||||
public:
|
||||
NBAcceptResult();
|
||||
|
||||
bool isFinished();
|
||||
bool isSuccess();
|
||||
|
||||
sock& get();
|
||||
|
||||
gerrno getErrCode();
|
||||
private:
|
||||
struct _impl;
|
||||
std::shared_ptr<_impl> _sp;
|
||||
|
||||
friend class serversock;
|
||||
};
|
||||
|
||||
class serversock : public vsock
|
||||
{
|
||||
public:
|
||||
|
@ -189,6 +207,7 @@ public:
|
|||
serversock(int use_family=0);
|
||||
~serversock();
|
||||
|
||||
// Notice that bind() should be called before setNonblocking()
|
||||
// Return:
|
||||
// GSOCK_OK: Bind Succeed. No Error.
|
||||
// GSOCK_API_ERROR: bind() call error. See errno.
|
||||
|
@ -202,6 +221,7 @@ public:
|
|||
// GSOCK_API_ERROR: setsockopt() call error.
|
||||
int set_reuse();
|
||||
|
||||
// Notice that listen() should be called before setNonblocking()
|
||||
// Return:
|
||||
// GSOCK_OK
|
||||
// GSOCK_API_ERROR: listen() call error.
|
||||
|
@ -213,6 +233,8 @@ public:
|
|||
// GSOCK_API_ERROR: accept() call error. See errno.
|
||||
// GSOCK_INVALID_SOCKET: _out_s is not an empty socket, which should not be passed in.
|
||||
int accept(sock& _out_s);
|
||||
// Notice that bind() and listen() should be called before setNonBlocking()
|
||||
NBAcceptResult accept_nb(sock& _out_s);
|
||||
private:
|
||||
struct _impl;
|
||||
_impl* _pp;
|
||||
|
|
Loading…
Reference in New Issue
Block a user