blob: 373e21d3e157d528414f5b243298f08d02d42fcc [file] [log] [blame]
David Klempnerdbb4f942015-01-21 17:45:18 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
David Klempnerdbb4f942015-01-21 17:45:18 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
murgatroid9954070892016-08-08 17:01:18 -070034#include "src/core/lib/iomgr/port.h"
David Klempnerdbb4f942015-01-21 17:45:18 -080035
murgatroid99623dd4f2016-08-08 17:31:27 -070036#ifdef GRPC_LINUX_EVENTFD
David Klempner78dc6cd2015-01-26 15:02:51 -080037
David Klempnerdbb4f942015-01-21 17:45:18 -080038#include <errno.h>
39#include <sys/eventfd.h>
40#include <unistd.h>
41
David Klempnerdbb4f942015-01-21 17:45:18 -080042#include <grpc/support/log.h>
43
Craig Tiller9533d042016-03-25 17:11:06 -070044#include "src/core/lib/iomgr/wakeup_fd_posix.h"
45#include "src/core/lib/profiling/timers.h"
Craig Tiller0ba432d2015-10-09 16:57:11 -070046
Craig Tiller0f75fbe2016-05-06 21:10:06 -070047static grpc_error* eventfd_create(grpc_wakeup_fd* fd_info) {
Craig Tillera82950e2015-09-22 12:33:20 -070048 int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
Craig Tiller0f75fbe2016-05-06 21:10:06 -070049 if (efd < 0) {
50 return GRPC_OS_ERROR(errno, "eventfd");
51 }
David Klempnerdbb4f942015-01-21 17:45:18 -080052 fd_info->read_fd = efd;
53 fd_info->write_fd = -1;
Craig Tiller0f75fbe2016-05-06 21:10:06 -070054 return GRPC_ERROR_NONE;
David Klempnerdbb4f942015-01-21 17:45:18 -080055}
56
Craig Tiller1aee5362016-05-07 11:26:50 -070057static grpc_error* eventfd_consume(grpc_wakeup_fd* fd_info) {
David Klempnerdbb4f942015-01-21 17:45:18 -080058 eventfd_t value;
59 int err;
Craig Tillera82950e2015-09-22 12:33:20 -070060 do {
61 err = eventfd_read(fd_info->read_fd, &value);
62 } while (err < 0 && errno == EINTR);
Craig Tillerf66c3742016-05-18 07:25:50 -070063 if (err < 0 && errno != EAGAIN) {
Craig Tiller0f75fbe2016-05-06 21:10:06 -070064 return GRPC_OS_ERROR(errno, "eventfd_read");
65 }
66 return GRPC_ERROR_NONE;
David Klempnerdbb4f942015-01-21 17:45:18 -080067}
68
Craig Tiller0f75fbe2016-05-06 21:10:06 -070069static grpc_error* eventfd_wakeup(grpc_wakeup_fd* fd_info) {
David Klempnerdbb4f942015-01-21 17:45:18 -080070 int err;
Craig Tiller0ba432d2015-10-09 16:57:11 -070071 GPR_TIMER_BEGIN("eventfd_wakeup", 0);
Craig Tillera82950e2015-09-22 12:33:20 -070072 do {
73 err = eventfd_write(fd_info->read_fd, 1);
74 } while (err < 0 && errno == EINTR);
Craig Tiller0f75fbe2016-05-06 21:10:06 -070075 if (err < 0) {
Craig Tillerac492c02016-05-18 07:19:56 -070076 return GRPC_OS_ERROR(errno, "eventfd_write");
Craig Tiller0f75fbe2016-05-06 21:10:06 -070077 }
Craig Tiller0ba432d2015-10-09 16:57:11 -070078 GPR_TIMER_END("eventfd_wakeup", 0);
Craig Tiller0f75fbe2016-05-06 21:10:06 -070079 return GRPC_ERROR_NONE;
David Klempnerdbb4f942015-01-21 17:45:18 -080080}
81
Craig Tillera82950e2015-09-22 12:33:20 -070082static void eventfd_destroy(grpc_wakeup_fd* fd_info) {
83 if (fd_info->read_fd != 0) close(fd_info->read_fd);
David Klempnerdbb4f942015-01-21 17:45:18 -080084}
85
Craig Tillera82950e2015-09-22 12:33:20 -070086static int eventfd_check_availability(void) {
David Garcia Quintas84d2e472016-06-29 14:53:46 -070087 const int efd = eventfd(0, 0);
88 const int is_available = efd >= 0;
89 if (is_available) close(efd);
90 return is_available;
David Klempner78dc6cd2015-01-26 15:02:51 -080091}
92
Craig Tillera3b18d92015-02-02 14:48:13 -080093const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable = {
Craig Tillera82950e2015-09-22 12:33:20 -070094 eventfd_create, eventfd_consume, eventfd_wakeup, eventfd_destroy,
95 eventfd_check_availability};
David Klempnerdbb4f942015-01-21 17:45:18 -080096
murgatroid99623dd4f2016-08-08 17:31:27 -070097#endif /* GRPC_LINUX_EVENTFD */