aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/iomgr/is_epollexclusive_available.cc
diff options
context:
space:
mode:
authorGravatar David Garcia Quintas <dgq@google.com>2017-11-02 16:33:36 -0700
committerGravatar David Garcia Quintas <dgq@google.com>2017-11-02 16:36:49 -0700
commit88933d803b148b02ecb7aad9a0395a72439d578f (patch)
tree97368c74ba0da51a69c8a1d14333097869d4bcb7 /src/core/lib/iomgr/is_epollexclusive_available.cc
parent2a95bf4d9a108a6bf7c8d081039d4bb1fd92fb71 (diff)
parent05547052d0394224515ac43364ce3a80467a5edc (diff)
Merge branch 'master' of github.com:grpc/grpc into grpclb_pick_from_shutdown_rr
Diffstat (limited to 'src/core/lib/iomgr/is_epollexclusive_available.cc')
-rw-r--r--src/core/lib/iomgr/is_epollexclusive_available.cc101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/core/lib/iomgr/is_epollexclusive_available.cc b/src/core/lib/iomgr/is_epollexclusive_available.cc
new file mode 100644
index 0000000000..d08844c0df
--- /dev/null
+++ b/src/core/lib/iomgr/is_epollexclusive_available.cc
@@ -0,0 +1,101 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/lib/iomgr/port.h"
+
+#include "src/core/lib/iomgr/is_epollexclusive_available.h"
+
+#ifdef GRPC_LINUX_EPOLL
+
+#include <grpc/support/log.h>
+
+#include <errno.h>
+#include <sys/eventfd.h>
+#include <unistd.h>
+
+#include "src/core/lib/iomgr/sys_epoll_wrapper.h"
+
+/* This polling engine is only relevant on linux kernels supporting epoll() */
+bool grpc_is_epollexclusive_available(void) {
+ static bool logged_why_not = false;
+
+ int fd = epoll_create1(EPOLL_CLOEXEC);
+ if (fd < 0) {
+ if (!logged_why_not) {
+ gpr_log(GPR_ERROR,
+ "epoll_create1 failed with error: %d. Not using epollex polling "
+ "engine.",
+ fd);
+ logged_why_not = true;
+ }
+ return false;
+ }
+ int evfd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
+ if (evfd < 0) {
+ if (!logged_why_not) {
+ gpr_log(GPR_ERROR,
+ "eventfd failed with error: %d. Not using epollex polling "
+ "engine.",
+ fd);
+ logged_why_not = true;
+ }
+ close(fd);
+ return false;
+ }
+ struct epoll_event ev;
+ /* choose events that should cause an error on
+ EPOLLEXCLUSIVE enabled kernels - specifically the combination of
+ EPOLLONESHOT and EPOLLEXCLUSIVE */
+ ev.events = (uint32_t)(EPOLLET | EPOLLIN | EPOLLEXCLUSIVE | EPOLLONESHOT);
+ ev.data.ptr = NULL;
+ if (epoll_ctl(fd, EPOLL_CTL_ADD, evfd, &ev) != 0) {
+ if (errno != EINVAL) {
+ if (!logged_why_not) {
+ gpr_log(
+ GPR_ERROR,
+ "epoll_ctl with EPOLLEXCLUSIVE | EPOLLONESHOT failed with error: "
+ "%d. Not using epollex polling engine.",
+ errno);
+ logged_why_not = true;
+ }
+ close(fd);
+ close(evfd);
+ return false;
+ }
+ } else {
+ if (!logged_why_not) {
+ gpr_log(GPR_ERROR,
+ "epoll_ctl with EPOLLEXCLUSIVE | EPOLLONESHOT succeeded. This is "
+ "evidence of no EPOLLEXCLUSIVE support. Not using "
+ "epollex polling engine.");
+ logged_why_not = true;
+ }
+ close(fd);
+ close(evfd);
+ return false;
+ }
+ close(evfd);
+ close(fd);
+ return true;
+}
+
+#else
+
+bool grpc_is_epollexclusive_available(void) { return false; }
+
+#endif