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.
|
// 3: finished, failed.
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
int errcode;
|
gerrno errcode;
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
};
|
};
|
||||||
|
@ -429,12 +429,12 @@ bool NBConnectResult::isFinished()
|
||||||
return (_p->status > 1);
|
return (_p->status > 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NBConnectResult::isConnected()
|
bool NBConnectResult::isSuccess()
|
||||||
{
|
{
|
||||||
return (_p->status == 2);
|
return (_p->status == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
int NBConnectResult::getErrCode()
|
gerrno NBConnectResult::getErrCode()
|
||||||
{
|
{
|
||||||
return _p->errcode;
|
return _p->errcode;
|
||||||
}
|
}
|
||||||
|
@ -650,7 +650,7 @@ NBConnectResult sock::connect_nb(const std::string& IPStr, int Port)
|
||||||
{
|
{
|
||||||
// Failed.
|
// Failed.
|
||||||
res._p->status = 3;
|
res._p->status = 3;
|
||||||
res._p->errcode = GSOCK_INVALID_IP;
|
res._p->errcode = (gerrno)GSOCK_INVALID_IP;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
res._p->saddr6.sin6_port = htons(Port);
|
res._p->saddr6.sin6_port = htons(Port);
|
||||||
|
@ -668,7 +668,7 @@ NBConnectResult sock::connect_nb(const std::string& IPStr, int Port)
|
||||||
{
|
{
|
||||||
// Failed.
|
// Failed.
|
||||||
res._p->status = 3;
|
res._p->status = 3;
|
||||||
res._p->errcode = GSOCK_INVALID_IP;
|
res._p->errcode = (gerrno)GSOCK_INVALID_IP;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
res._p->saddr.sin_port = htons(Port);
|
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;
|
res._p->status = 1;
|
||||||
}
|
}
|
||||||
else
|
else // xret is a GSock error
|
||||||
{
|
{
|
||||||
// Failed
|
// Failed
|
||||||
res._p->status = 3;
|
res._p->status = 3;
|
||||||
res._p->errcode = xret;
|
res._p->errcode = (gerrno)xret;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1000,6 +1000,93 @@ int serversock::listen(int MaxCount)
|
||||||
return ::listen(_vp->sfd,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)
|
int serversock::accept(sock& _out_s)
|
||||||
{
|
{
|
||||||
if( (!_vp->created) || (_out_s._vp->created) )
|
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
|
struct udpsock::_impl
|
||||||
{
|
{
|
||||||
int protocol;
|
int protocol;
|
||||||
|
|
30
gsock.h
30
gsock.h
|
@ -29,11 +29,11 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
// Internal Socket Call Errcode
|
// Internal Socket Call Errcode
|
||||||
|
// Values of all errors are positive number.
|
||||||
enum gerrno
|
enum gerrno
|
||||||
{
|
{
|
||||||
UnknownError = -1,
|
|
||||||
OK = 0,
|
OK = 0,
|
||||||
// Values of all known errors are positive number.
|
UnknownError,
|
||||||
WouldBlock,
|
WouldBlock,
|
||||||
InProgress,
|
InProgress,
|
||||||
Already,
|
Already,
|
||||||
|
@ -78,9 +78,9 @@ public:
|
||||||
bool isFinished();
|
bool isFinished();
|
||||||
// Wait until the connection is finished. (via while loop)
|
// Wait until the connection is finished. (via while loop)
|
||||||
void wait();
|
void wait();
|
||||||
bool isConnected();
|
bool isSuccess();
|
||||||
// ErrCode is only usable when the connection is finished and failed.
|
// ErrCode is only usable when the connection is finished and failed.
|
||||||
int getErrCode();
|
gerrno getErrCode();
|
||||||
private:
|
private:
|
||||||
struct _impl;
|
struct _impl;
|
||||||
std::shared_ptr<_impl> _p;
|
std::shared_ptr<_impl> _p;
|
||||||
|
@ -179,6 +179,24 @@ private:
|
||||||
struct _impl;
|
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
|
class serversock : public vsock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -189,6 +207,7 @@ public:
|
||||||
serversock(int use_family=0);
|
serversock(int use_family=0);
|
||||||
~serversock();
|
~serversock();
|
||||||
|
|
||||||
|
// Notice that bind() should be called before setNonblocking()
|
||||||
// Return:
|
// Return:
|
||||||
// GSOCK_OK: Bind Succeed. No Error.
|
// GSOCK_OK: Bind Succeed. No Error.
|
||||||
// GSOCK_API_ERROR: bind() call error. See errno.
|
// GSOCK_API_ERROR: bind() call error. See errno.
|
||||||
|
@ -202,6 +221,7 @@ public:
|
||||||
// GSOCK_API_ERROR: setsockopt() call error.
|
// GSOCK_API_ERROR: setsockopt() call error.
|
||||||
int set_reuse();
|
int set_reuse();
|
||||||
|
|
||||||
|
// Notice that listen() should be called before setNonblocking()
|
||||||
// Return:
|
// Return:
|
||||||
// GSOCK_OK
|
// GSOCK_OK
|
||||||
// GSOCK_API_ERROR: listen() call error.
|
// GSOCK_API_ERROR: listen() call error.
|
||||||
|
@ -213,6 +233,8 @@ public:
|
||||||
// GSOCK_API_ERROR: accept() call error. See errno.
|
// GSOCK_API_ERROR: accept() call error. See errno.
|
||||||
// GSOCK_INVALID_SOCKET: _out_s is not an empty socket, which should not be passed in.
|
// GSOCK_INVALID_SOCKET: _out_s is not an empty socket, which should not be passed in.
|
||||||
int accept(sock& _out_s);
|
int accept(sock& _out_s);
|
||||||
|
// Notice that bind() and listen() should be called before setNonBlocking()
|
||||||
|
NBAcceptResult accept_nb(sock& _out_s);
|
||||||
private:
|
private:
|
||||||
struct _impl;
|
struct _impl;
|
||||||
_impl* _pp;
|
_impl* _pp;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user