Skip to content

Commit 7ca4f64

Browse files
committed
fix(event): 解决select中遇到失效了fd退出循环的问题
1 parent e8aced0 commit 7ca4f64

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

modules/event/engines/select/loop.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* of the source tree.
1919
*/
2020
#include <sys/select.h>
21+
#include <fcntl.h>
2122

2223
#include <cstring>
2324
#include <algorithm>
@@ -75,8 +76,16 @@ void SelectLoop::runLoop(Mode mode)
7576
}
7677
}
7778
} else if (select_ret == -1) {
78-
LogErrno(errno, "select error");
79-
break;
79+
if (errno == EBADF) {
80+
removeInvalidFds();
81+
82+
} else if (errno != EINTR) {
83+
LogErrno(errno, "select error");
84+
break;
85+
86+
} else {
87+
LogNotice("select errno:%d(%s)", errno, strerror(errno));
88+
}
8089
}
8190

8291
//handleRunInLoopFunc();
@@ -126,6 +135,28 @@ int SelectLoop::fillFdSets(fd_set &read_set, fd_set &write_set, fd_set &except_s
126135
return max_fd + 1;
127136
}
128137

138+
bool IsFdValid(int fd)
139+
{
140+
if (fd < 0)
141+
return false;
142+
143+
return ::fcntl(fd, F_GETFD) != -1 || errno != EBADF;
144+
}
145+
146+
void SelectLoop::removeInvalidFds()
147+
{
148+
for (auto item : fd_data_map_) {
149+
auto fd = item.first;
150+
if (!IsFdValid(fd)) {
151+
LogWarn("fd:%d is invalid", fd);
152+
SelectFdSharedData *data = item.second;
153+
for (auto event : data->fd_events) {
154+
event->disable();
155+
}
156+
}
157+
}
158+
}
159+
129160
SelectFdSharedData* SelectLoop::refFdSharedData(int fd)
130161
{
131162
SelectFdSharedData *fd_shared_data = nullptr;

modules/event/engines/select/loop.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class SelectLoop : public CommonLoop {
4646
protected:
4747
virtual void stopLoop() override { keep_running_ = false; }
4848
int fillFdSets(fd_set &read_set, fd_set &write_set, fd_set &except_set);
49+
void removeInvalidFds(); //! 清除失效了的fd
4950

5051
private:
5152
bool keep_running_ = true;

modules/event/fd_event_test.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ TEST(FdEvent, Exception)
371371
EXPECT_TRUE(read_fd_event->initialize(read_fd, FdEvent::kReadEvent | FdEvent::kHupEvent, Event::Mode::kPersist));
372372
read_fd_event->setCallback([&](short events){
373373
if (events & FdEvent::kReadEvent) {
374-
char data[100] = { 0};
374+
char data[100] = { 0 };
375375
ssize_t len = read(read_fd, data, sizeof(data));
376376
EXPECT_EQ(len, sizeof(int));
377377
}
@@ -396,6 +396,7 @@ TEST(FdEvent, Exception)
396396

397397
write_fd_event->enable();
398398

399+
loop->exitLoop(std::chrono::milliseconds(10));
399400
loop->runLoop();
400401

401402
EXPECT_EQ(run_time, 1);

0 commit comments

Comments
 (0)