Skip to content

Commit fa40dad

Browse files
committed
修复bug和优化逻辑
1 parent 835d8f9 commit fa40dad

File tree

4 files changed

+131
-136
lines changed

4 files changed

+131
-136
lines changed

src/epoll/Epoll.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,26 @@ namespace net
6868
void * vdata = _events[i].data.ptr;
6969
if (!vdata) continue;
7070

71-
SEpollEvent* epdata = (SEpollEvent*)vdata;
72-
if (epdata->_type == SEpollEvent::eEPV_ACCPET) {
73-
SEpollAccept* acceptr = (SEpollAccept*)epdata;
71+
SEpollEvent* evt = (SEpollEvent*)vdata;
72+
if (evt->_type == SEpollEvent::eEPV_ACCPET) {
73+
SEpollAccept* acceptr = (SEpollAccept*)evt;
7474
if (acceptr) {
7575
acceptr->accept->onEpollAccept(_events[i].events);
7676
}
7777
}
78-
else if (epdata->_type == SEpollEvent::eEPV_SOCKET)
78+
else if (evt->_type == SEpollEvent::eEPV_SOCKET)
7979
{
80-
SEpollSocket* ioptr = (SEpollSocket*)epdata;
81-
if (ioptr) {
82-
IoSockptr& ptr = ioptr->inptr ? ioptr->inptr : ioptr->outptr;
83-
if(ptr) ptr->onEpollEv(_events[i].events);
80+
SEpollSocket* evs = (SEpollSocket*)evt;
81+
if (evs) {
82+
//EPOLLERR: opposite close
83+
//EPOLLHUP: shtdown
84+
uint32 iev = _events[i].events;
85+
IoSockptr ptr = (iev & EPOLLERR || iev & EPOLLHUP) ?
86+
std::move(evs->sockptr) : evs->sockptr;
87+
88+
if (ptr) {
89+
ptr->onEpollEv(iev);
90+
}
8491
}
8592
}
8693
}

src/epoll/IoSocket.cpp

Lines changed: 94 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,23 @@
33
namespace net
44
{
55

6-
IoSocket::IoSocket()
6+
IoSocket::IoSocket():
7+
_close(false)
78
{
89
_fd = INVALID_SOCKET;
910
_loop = NULL;
1011
_event._type = SEpollEvent::eEPV_SOCKET;
1112
_event._ev.data.ptr = &_event;
1213

13-
isconnect = false;
14+
_isconnect = false;
1415
_recv.reset();
1516
_writeBuf = NULL;
1617
_writeLen = 0;
1718
}
1819

1920
IoSocket::~IoSocket()
2021
{
21-
close();
22+
finalClose();
2223
}
2324

2425
bool IoSocket::connect(NetLoop* loop, const char* ip, unsigned short port)
@@ -40,13 +41,15 @@ namespace net
4041
}
4142

4243
_event._ev.events = EPOLLET | EPOLLOUT;
43-
_event.outptr = shared_from_this();
44-
loop->registerEpoll(EPOLL_CTL_ADD, fd, &_event._ev);
44+
if (!loop->registerEpoll(EPOLL_CTL_ADD, fd, &_event._ev))
45+
{
46+
return false;
47+
}
4548

4649
_fd = fd;
4750
_loop = loop;
48-
isconnect = true;
49-
51+
_isconnect = true;
52+
_event.sockptr = shared_from_this();
5053
return true;
5154
}
5255

@@ -68,13 +71,17 @@ namespace net
6871
}
6972

7073
_event._ev.events = EPOLLET | EPOLLOUT;
71-
_event.outptr = shared_from_this();
72-
_loop->registerEpoll(EPOLL_CTL_ADD, fd, &_event._ev);
73-
74+
if (!_loop->registerEpoll(EPOLL_CTL_ADD, fd, &_event._ev))
75+
{
76+
return false;
77+
}
78+
7479
_fd = fd;
75-
isconnect = true;
80+
_isconnect = true;
81+
_event.sockptr = shared_from_this();
7682
return true;
7783
}
84+
7885
bool IoSocket::write(char* buf, int len)
7986
{
8087
int ret = send(_fd, buf, len, 0);
@@ -88,8 +95,10 @@ namespace net
8895

8996
//EPOLLOUT
9097
_event._ev.events = _event._ev.events | EPOLLOUT;
91-
_event.outptr = shared_from_this();
92-
_loop->registerEpoll(EPOLL_CTL_MOD, _fd, &_event._ev);
98+
if (!_loop->registerEpoll(EPOLL_CTL_MOD, _fd, &_event._ev)){
99+
return false;
100+
}
101+
_event.sockptr = shared_from_this();
93102
}
94103
else
95104
{
@@ -99,21 +108,25 @@ namespace net
99108
return true;
100109

101110
}
111+
102112
bool IoSocket::read(char* buf, int len)
103113
{
114+
if (buf == NULL || len <= 0) return false;
115+
104116
if (!(_event._ev.events & EPOLLIN))
105117
{
106118
_event._ev.events = _event._ev.events | EPOLLIN;
107-
_loop->registerEpoll(EPOLL_CTL_MOD, _fd, &_event._ev);
119+
if (!_loop->registerEpoll(EPOLL_CTL_MOD, _fd, &_event._ev)){
120+
return false;
121+
}
122+
_event.sockptr = shared_from_this();
108123
}
109124

110-
_event.inptr = shared_from_this();
111-
112125
_recv._recvBuf = buf;
113126
_recv._recvLen = len;
114-
115-
handleRead();
116-
127+
if (_recv._hasData) {
128+
handleRead();
129+
}
117130
return true;
118131
}
119132

@@ -128,142 +141,108 @@ namespace net
128141

129142
void IoSocket::onEpollEv(uint32 ev)
130143
{
131-
if (isconnect)
144+
if (_isconnect)
132145
{
133-
int result = 0;
134-
if (ev & EPOLLERR || ev & EPOLLHUP)
135-
{
136-
//WRITE_LOG("IoSocket::onEpollEv EPOLLERR || EPOLLHUP errno: %d error:%s, line:%d\n", errno, strerror(errno), __LINE__);
137-
result = errno;
138-
}
139-
else if (ev & EPOLLOUT)
140-
{
141-
//连接成功
142-
result = 0;
146+
_isconnect = false;
147+
if (ev & EPOLLERR || ev & EPOLLHUP){
148+
this->finalClose(); //reconnect close this socket
149+
onConnect(errno == 0 ? 0xffffffff : errno);
143150
}
144-
else
145-
{
146-
WRITE_LOG("IoSocket::onEpollEv Handling Exceptions line:%d\n", __LINE__);
147-
return;
148-
}
149-
150-
isconnect = false;
151-
IoSockptr tmpptr(std::move(_event.outptr));
152-
if (result == 0) {
151+
else if (ev & EPOLLOUT){ //connect success
153152
_event._ev.events = _event._ev.events & ~EPOLLOUT;
154153
_loop->registerEpoll(EPOLL_CTL_MOD, _fd, &_event._ev);
154+
onConnect(0);
155155
}
156156
else{
157-
this->close();
157+
assert(0);
158158
}
159-
onConnect(result);
160159
return;
161160
}
162161

163-
if (ev & EPOLLHUP || ev & EPOLLERR)
164-
{
165-
WRITE_LOG("IoSocket::onEpollEv EPOLLERR || EPOLLHUP errno: %d error:%s, line:%d\n", errno, strerror(errno), __LINE__);
166-
IoSockptr inptr(std::move(_event.inptr));
167-
IoSockptr outptr(std::move(_event.outptr));
168-
this->close();
169-
onRead(0, errno);
162+
if (ev & EPOLLHUP ||//shtdown (recive bytes == 0 && errno == 0)
163+
ev & EPOLLERR){ //opposite close (errno > 0)
164+
onRead(0, errno == 0 ? 0xffffffff: errno);
170165
return;
171166
}
172167

173-
//read
168+
174169
if (ev & EPOLLIN)
175170
{
176-
177-
_recv._isRead = true;
178-
handleRead();
179-
#if 0
180-
int ret = recv(_fd, _recvBuf, _recvLen, 0);
181-
if (ret < 0){
182-
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK){
183-
return;
184-
}
185-
else{
186-
onRead(ret, errno);
187-
return;
188-
}
189-
}
190-
else if (ret == 0){
191-
//close
192-
onRead(ret, errno);
193-
return;
171+
_recv._hasData = true;
172+
if (_recv.isValid()) {
173+
handleRead();
194174
}
195-
onRead(ret, 0);
196-
#endif
197175
}
198-
199-
//write
200-
if (ev & EPOLLOUT)
176+
else if (ev & EPOLLOUT)
201177
{
202178
int err = 0;
203-
int ret = send(_fd, _writeBuf, _writeLen, 0);
204-
if (ret < 0)
179+
while(1)
205180
{
206-
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
207-
return;
181+
int ret = send(_fd, _writeBuf, _writeLen, 0);
182+
if (ret < 0)
183+
{
184+
if (errno == EINTR) continue;
185+
if (errno == EAGAIN || errno == EWOULDBLOCK) {
186+
return;
187+
}
188+
else {
189+
err = errno;
190+
}
208191
}
209-
else {
210-
//onWrite(ret, errno);
211-
//return;
212-
err = errno;
213-
}
214-
}
215192

216-
//取消EPOLLOUT
217-
_event._ev.events = _event._ev.events & ~EPOLLOUT;
218-
_loop->registerEpoll(EPOLL_CTL_MOD, _fd, &_event._ev);
219-
IoSockptr tmpptr(std::move(_event.outptr));
193+
//È¡ÏûEPOLLOUT
194+
_event._ev.events = _event._ev.events & ~EPOLLOUT;
195+
_loop->registerEpoll(EPOLL_CTL_MOD, _fd, &_event._ev);
220196

221-
onWrite(ret, err);
197+
onWrite(ret, err);
198+
return;//exec one
199+
};
222200
}
223201
}
224202

225-
void IoSocket::handleRead()
203+
bool IoSocket::handleRead()
226204
{
227-
if (!_recv.isValid() || !_recv._isRead) return;
228-
229-
int result = 0;
230-
//while(1){ recv();} ==> 替换成在onRead递归
231-
int ret = recv(_fd, _recv._recvBuf, _recv._recvLen, 0);
232-
if (ret < 0) {
233-
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
234-
return;
205+
while(1)
206+
{
207+
int result = 0;
208+
int bytes = recv(_fd, _recv._recvBuf, _recv._recvLen, 0);
209+
if (bytes < 0) {
210+
if (errno == EINTR) continue;
211+
if (errno == EAGAIN || errno == EWOULDBLOCK) {
212+
return false;
213+
}
214+
_recv._hasData = false;
215+
result = errno;
235216
}
236-
else {
237-
_recv._isRead = false;
217+
else if (bytes == 0){//close
218+
_recv._hasData = false;
238219
result = errno;
239220
}
240-
}
241-
else if (ret == 0) {
242-
//close
243-
_recv._isRead = false;
244-
result = errno;
245-
}
246-
else {
247-
//ret > 0
248-
}
249221

250-
_recv._recvBuf = NULL;
251-
_recv._recvLen = 0;
252-
IoSockptr tmpptr(std::move(_event.inptr));
253-
onRead(ret, result);
222+
_recv.setInvalid();
223+
onRead(bytes, result);
224+
return true;//exec one
225+
226+
};
254227
}
255228

256229
void IoSocket::close()
230+
{
231+
if (_close) return;
232+
_close = true;
233+
234+
if (_fd != INVALID_SOCKET){
235+
::shutdown(_fd, SHUT_RDWR);
236+
}
237+
}
238+
239+
void IoSocket::finalClose()
257240
{
258241
if (_fd != INVALID_SOCKET)
259242
{
260-
_event.inptr = nullptr;
261-
_event.outptr = nullptr;
262-
263243
if (_loop) {
264244
_loop->registerEpoll(EPOLL_CTL_DEL, _fd, &_event._ev);
265245
}
266-
::shutdown(_fd, SHUT_RDWR);
267246
::close(_fd);
268247
_fd = INVALID_SOCKET;
269248
}

0 commit comments

Comments
 (0)