blob: d08844c0dfda98a6ad2ade997f2ca9711335f42f [file] [log] [blame]
Craig Tiller819cd882017-04-25 13:18:22 -07001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2017 gRPC authors.
Craig Tiller819cd882017-04-25 13:18:22 -07004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
Craig Tiller819cd882017-04-25 13:18:22 -07008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Craig Tiller819cd882017-04-25 13:18:22 -070010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
Craig Tiller819cd882017-04-25 13:18:22 -070016 *
17 */
18
19#include "src/core/lib/iomgr/port.h"
20
21#include "src/core/lib/iomgr/is_epollexclusive_available.h"
22
23#ifdef GRPC_LINUX_EPOLL
24
25#include <grpc/support/log.h>
26
27#include <errno.h>
28#include <sys/eventfd.h>
29#include <unistd.h>
30
31#include "src/core/lib/iomgr/sys_epoll_wrapper.h"
32
33/* This polling engine is only relevant on linux kernels supporting epoll() */
34bool grpc_is_epollexclusive_available(void) {
35 static bool logged_why_not = false;
36
37 int fd = epoll_create1(EPOLL_CLOEXEC);
38 if (fd < 0) {
39 if (!logged_why_not) {
40 gpr_log(GPR_ERROR,
41 "epoll_create1 failed with error: %d. Not using epollex polling "
42 "engine.",
43 fd);
44 logged_why_not = true;
45 }
46 return false;
47 }
48 int evfd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
49 if (evfd < 0) {
50 if (!logged_why_not) {
51 gpr_log(GPR_ERROR,
52 "eventfd failed with error: %d. Not using epollex polling "
53 "engine.",
54 fd);
55 logged_why_not = true;
56 }
57 close(fd);
58 return false;
59 }
Yash Tibrewal533d1182017-09-18 10:48:22 -070060 struct epoll_event ev;
61 /* choose events that should cause an error on
62 EPOLLEXCLUSIVE enabled kernels - specifically the combination of
63 EPOLLONESHOT and EPOLLEXCLUSIVE */
64 ev.events = (uint32_t)(EPOLLET | EPOLLIN | EPOLLEXCLUSIVE | EPOLLONESHOT);
65 ev.data.ptr = NULL;
Craig Tiller819cd882017-04-25 13:18:22 -070066 if (epoll_ctl(fd, EPOLL_CTL_ADD, evfd, &ev) != 0) {
67 if (errno != EINVAL) {
68 if (!logged_why_not) {
69 gpr_log(
70 GPR_ERROR,
71 "epoll_ctl with EPOLLEXCLUSIVE | EPOLLONESHOT failed with error: "
72 "%d. Not using epollex polling engine.",
73 errno);
74 logged_why_not = true;
75 }
76 close(fd);
77 close(evfd);
78 return false;
79 }
80 } else {
81 if (!logged_why_not) {
82 gpr_log(GPR_ERROR,
83 "epoll_ctl with EPOLLEXCLUSIVE | EPOLLONESHOT succeeded. This is "
84 "evidence of no EPOLLEXCLUSIVE support. Not using "
85 "epollex polling engine.");
86 logged_why_not = true;
87 }
88 close(fd);
89 close(evfd);
90 return false;
91 }
92 close(evfd);
93 close(fd);
94 return true;
95}
96
97#else
98
99bool grpc_is_epollexclusive_available(void) { return false; }
100
101#endif