Skip to content

Commit 1916ff6

Browse files
committed
Add config option to determine whether eventfd is used.
Add a new configuration option "reactor" / "use_eventfd" that is used by the epoll_reactor. When true (the default), the reactor uses an eventfd as its select_interrupter implementation. When false, a pipe is used instead.
1 parent fb037cf commit 1916ff6

File tree

8 files changed

+47
-32
lines changed

8 files changed

+47
-32
lines changed

include/asio/detail/eventfd_select_interrupter.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class eventfd_select_interrupter
2929
{
3030
public:
3131
// Constructor.
32-
ASIO_DECL eventfd_select_interrupter();
32+
ASIO_DECL explicit eventfd_select_interrupter(bool use_eventfd = true);
3333

3434
// Destructor.
3535
ASIO_DECL ~eventfd_select_interrupter();
@@ -51,7 +51,7 @@ class eventfd_select_interrupter
5151

5252
private:
5353
// Open the descriptors. Throws on error.
54-
ASIO_DECL void open_descriptors();
54+
ASIO_DECL void open_descriptors(bool use_eventfd);
5555

5656
// Close the descriptors.
5757
ASIO_DECL void close_descriptors();

include/asio/detail/impl/epoll_reactor.ipp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ epoll_reactor::epoll_reactor(asio::execution_context& ctx)
4141
scheduler_(use_service<scheduler>(ctx)),
4242
mutex_(config(ctx).get("reactor", "registration_locking", true),
4343
config(ctx).get("reactor", "registration_locking_spin_count", 0)),
44-
interrupter_(),
44+
interrupter_(config(ctx).get("reactor", "use_eventfd", true)),
4545
epoll_fd_(do_epoll_create()),
4646
timer_fd_(config(ctx).get("reactor", "use_timerfd", true)
4747
? do_timerfd_create() : -1),

include/asio/detail/impl/eventfd_select_interrupter.ipp

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,38 +38,43 @@
3838
namespace asio {
3939
namespace detail {
4040

41-
eventfd_select_interrupter::eventfd_select_interrupter()
41+
eventfd_select_interrupter::eventfd_select_interrupter(bool use_eventfd)
4242
{
43-
open_descriptors();
43+
open_descriptors(use_eventfd);
4444
}
4545

46-
void eventfd_select_interrupter::open_descriptors()
46+
void eventfd_select_interrupter::open_descriptors(bool use_eventfd)
4747
{
48-
#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 && !defined(__UCLIBC__)
49-
write_descriptor_ = read_descriptor_ = syscall(__NR_eventfd, 0);
50-
if (read_descriptor_ != -1)
48+
if (use_eventfd)
5149
{
52-
::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
53-
::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC);
54-
}
50+
#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 && !defined(__UCLIBC__)
51+
write_descriptor_ = read_descriptor_ = syscall(__NR_eventfd, 0);
52+
if (read_descriptor_ != -1)
53+
{
54+
::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
55+
::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC);
56+
}
5557
#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 && !defined(__UCLIBC__)
5658
# if defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK)
57-
write_descriptor_ = read_descriptor_ =
58-
::eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
59+
write_descriptor_ = read_descriptor_ =
60+
::eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
5961
# else // defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK)
60-
errno = EINVAL;
61-
write_descriptor_ = read_descriptor_ = -1;
62+
errno = EINVAL;
63+
write_descriptor_ = read_descriptor_ = -1;
6264
# endif // defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK)
63-
if (read_descriptor_ == -1 && errno == EINVAL)
64-
{
65-
write_descriptor_ = read_descriptor_ = ::eventfd(0, 0);
66-
if (read_descriptor_ != -1)
65+
if (read_descriptor_ == -1 && errno == EINVAL)
6766
{
68-
::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
69-
::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC);
67+
write_descriptor_ = read_descriptor_ = ::eventfd(0, 0);
68+
if (read_descriptor_ != -1)
69+
{
70+
::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
71+
::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC);
72+
}
7073
}
71-
}
7274
#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 && !defined(__UCLIBC__)
75+
}
76+
else
77+
write_descriptor_ = read_descriptor_ = -1;
7378

7479
if (read_descriptor_ == -1)
7580
{
@@ -107,12 +112,10 @@ void eventfd_select_interrupter::close_descriptors()
107112

108113
void eventfd_select_interrupter::recreate()
109114
{
115+
bool use_eventfd = (write_descriptor_ == read_descriptor_);
110116
close_descriptors();
111-
112-
write_descriptor_ = -1;
113-
read_descriptor_ = -1;
114-
115-
open_descriptors();
117+
write_descriptor_ = read_descriptor_ = -1;
118+
open_descriptors(use_eventfd);
116119
}
117120

118121
void eventfd_select_interrupter::interrupt()

include/asio/detail/impl/pipe_select_interrupter.ipp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
namespace asio {
3838
namespace detail {
3939

40-
pipe_select_interrupter::pipe_select_interrupter()
40+
pipe_select_interrupter::pipe_select_interrupter(bool)
4141
{
4242
open_descriptors();
4343
}

include/asio/detail/impl/socket_select_interrupter.ipp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
namespace asio {
3636
namespace detail {
3737

38-
socket_select_interrupter::socket_select_interrupter()
38+
socket_select_interrupter::socket_select_interrupter(bool)
3939
{
4040
open_descriptors();
4141
}

include/asio/detail/pipe_select_interrupter.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class pipe_select_interrupter
3232
{
3333
public:
3434
// Constructor.
35-
ASIO_DECL pipe_select_interrupter();
35+
ASIO_DECL explicit pipe_select_interrupter(bool = true);
3636

3737
// Destructor.
3838
ASIO_DECL ~pipe_select_interrupter();

include/asio/detail/socket_select_interrupter.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class socket_select_interrupter
3434
{
3535
public:
3636
// Constructor.
37-
ASIO_DECL socket_select_interrupter();
37+
ASIO_DECL explicit socket_select_interrupter(bool = true);
3838

3939
// Destructor.
4040
ASIO_DECL ~socket_select_interrupter();

src/doc/overview/configuration.qbk

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,18 @@ below.
177177
fails with `EAGAIN`.
178178
]
179179
]
180+
[
181+
[`reactor`]
182+
[`use_eventfd`]
183+
[`bool`]
184+
[`true`]
185+
[
186+
Linux [^epoll] backend only.
187+
188+
When `true`, the reactor uses an [^eventfd] descriptor to wake a blocked
189+
[^epoll_wait] call. When `false`, a pipe is used instead.
190+
]
191+
]
180192
[
181193
[`reactor`]
182194
[`use_timerfd`]

0 commit comments

Comments
 (0)