Skip to content

Commit 36c7ed7

Browse files
author
Lluís Vilanova
committed
drivers/unix_socket: Use ppoll to monitor file descriptors
Using ppoll() instead of epoll_pwait() saves us from using one additional file descriptor per instance, without introducing any measurable performance overhead.
1 parent c9c6218 commit 36c7ed7

2 files changed

Lines changed: 30 additions & 69 deletions

File tree

core/drivers/unix_socket.cc

Lines changed: 30 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
// POSSIBILITY OF SUCH DAMAGE.
3030

3131
#include <signal.h>
32-
#include <sys/epoll.h>
32+
#include <poll.h>
3333

3434
#include "unix_socket.h"
3535

@@ -44,73 +44,51 @@
4444
#define SIG_THREAD_EXIT SIGUSR2
4545

4646

47-
static void EpollAdd(int epoll_fd, int new_fd, uint32_t events) {
48-
struct epoll_event event;
49-
event.events = events;
50-
event.data.fd = new_fd;
51-
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, new_fd, &event);
52-
}
53-
54-
static void EpollDel(int epoll_fd, int fd) {
55-
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, nullptr);
56-
}
57-
5847
void UnixSocketPort::AcceptThread() {
5948
sigset_t sigset;
6049
sigfillset(&sigset);
6150
sigdelset(&sigset, SIG_THREAD_EXIT);
6251

52+
struct pollfd fds[2];
53+
memset(fds, 0, sizeof(fds));
54+
fds[0].fd = listen_fd_;
55+
fds[0].events = POLLIN;
56+
fds[1].events = POLLRDHUP;
57+
6358
while (true) {
64-
struct epoll_event event;
65-
if (epoll_pwait(epoll_fd_, &event, 1, -1, &sigset) < 0) {
59+
fds[1].fd = client_fd_;
60+
int res = ppoll(fds, 2, nullptr, &sigset);
61+
62+
if (accept_thread_stop_req_) {
63+
return;
64+
65+
} else if (res < 0) {
6666
if (errno == EINTR) {
67-
if (accept_thread_stop_req_) {
68-
break;
69-
} else {
70-
continue;
71-
}
67+
continue;
7268
} else {
7369
PLOG(ERROR) << "[UnixSocketPort]:epoll_wait()";
7470
}
7571

76-
} else if (event.data.fd == listen_fd_) {
77-
if (event.events & EPOLLIN) {
78-
// new client connected
79-
int fd;
80-
while (true) {
81-
fd = accept4(listen_fd_, nullptr, nullptr, SOCK_NONBLOCK);
82-
if (fd >= 0 || errno != EINTR) {
83-
break;
84-
}
85-
}
86-
if (fd < 0) {
87-
PLOG(ERROR) << "[UnixSocketPort]:accept4()";
88-
} else {
89-
EpollAdd(epoll_fd_, fd, EPOLLRDHUP);
90-
client_fd_ = fd;
72+
} else if (fds[0].revents & POLLIN) {
73+
// new client connected
74+
int fd;
75+
while (true) {
76+
fd = accept4(listen_fd_, nullptr, nullptr, SOCK_NONBLOCK);
77+
if (fd >= 0 || errno != EINTR) {
78+
break;
9179
}
92-
} else {
93-
LOG(ERROR) << "[UnixSocketPort]:epoll_wait(): "
94-
<< "Unexpected event " << event.events
95-
<< " in listen_fd_";
9680
}
97-
98-
} else if (event.data.fd == client_fd_) {
99-
if (event.events & EPOLLRDHUP) {
100-
// connection dropped by client
101-
int fd = client_fd_;
102-
client_fd_ = -1;
103-
EpollDel(epoll_fd_, fd);
104-
close(fd);
81+
if (fd < 0) {
82+
PLOG(ERROR) << "[UnixSocketPort]:accept4()";
10583
} else {
106-
LOG(ERROR) << "[UnixSocketPort]:epoll_wait(): "
107-
<< "Unexpected event " << event.events
108-
<< " in client_fd_";
84+
client_fd_ = fd;
10985
}
11086

111-
} else {
112-
LOG(ERROR) << "[UnixSocketPort]:epoll_wait(): "
113-
<< "Unexpected fd " << event.data.fd;
87+
} else if (fds[1].revents & (POLLRDHUP | POLLHUP)) {
88+
// connection dropped by client
89+
int fd = client_fd_;
90+
client_fd_ = -1;
91+
close(fd);
11492
}
11593
}
11694
}
@@ -171,14 +149,6 @@ CommandResponse UnixSocketPort::Init(const bess::pb::UnixSocketPortArg &arg) {
171149
}
172150

173151

174-
epoll_fd_ = epoll_create(1);
175-
if (epoll_fd_ < 0) {
176-
DeInit();
177-
return CommandFailure(errno, "epoll_create(1) failed");
178-
}
179-
EpollAdd(epoll_fd_, listen_fd_, EPOLLIN);
180-
181-
182152
struct sigaction sa;
183153
memset(&sa, 0, sizeof(sa));
184154
sa.sa_handler = AcceptThreadHandler;
@@ -208,9 +178,6 @@ void UnixSocketPort::DeInit() {
208178
if (client_fd_ != kNotConnectedFd) {
209179
close(client_fd_);
210180
}
211-
if (epoll_fd_ != kNotConnectedFd) {
212-
close(epoll_fd_);
213-
}
214181
}
215182

216183
int UnixSocketPort::RecvPackets(queue_t qid, bess::Packet **pkts, int cnt) {

core/drivers/unix_socket.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ class UnixSocketPort final : public Port {
5959
accept_thread_stop_req_(false),
6060
listen_fd_(kNotConnectedFd),
6161
addr_(),
62-
epoll_fd_(kNotConnectedFd),
6362
client_fd_(kNotConnectedFd) {}
6463

6564
/*!
@@ -145,11 +144,6 @@ class UnixSocketPort final : public Port {
145144
*/
146145
struct sockaddr_un addr_;
147146

148-
/*!
149-
* The epoll fd -- detect when client closes.
150-
*/
151-
int epoll_fd_;
152-
153147
// NOTE: three threads (accept / recv / send) may race on this, so use
154148
// volatile.
155149
/* FD for client connection.*/

0 commit comments

Comments
 (0)