blob: e186d6368371d53942233b5760fb886f3407fbd4 [file] [log] [blame]
David Klempner78dc6cd2015-01-26 15:02:51 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
David Klempner78dc6cd2015-01-26 15:02:51 -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"
Nicolas "Pixel" Noblec8fd2d12015-01-30 20:23:27 +010035
murgatroid99623dd4f2016-08-08 17:31:27 -070036#ifdef GRPC_POSIX_WAKEUP_FD
Nicolas "Pixel" Noblec8fd2d12015-01-30 20:23:27 +010037
Craig Tiller9533d042016-03-25 17:11:06 -070038#include "src/core/lib/iomgr/wakeup_fd_posix.h"
David Klempner78dc6cd2015-01-26 15:02:51 -080039
40#include <errno.h>
41#include <string.h>
42#include <unistd.h>
43
David Klempner78dc6cd2015-01-26 15:02:51 -080044#include <grpc/support/log.h>
45
Craig Tiller9533d042016-03-25 17:11:06 -070046#include "src/core/lib/iomgr/socket_utils_posix.h"
Craig Tiller1f375d72016-03-17 07:47:18 -070047
Craig Tiller4f1d0f32016-05-06 17:12:37 -070048static grpc_error* pipe_init(grpc_wakeup_fd* fd_info) {
David Klempner78dc6cd2015-01-26 15:02:51 -080049 int pipefd[2];
Craig Tiller9474c4a2016-02-25 07:02:39 -080050 int r = pipe(pipefd);
51 if (0 != r) {
52 gpr_log(GPR_ERROR, "pipe creation failed (%d): %s", errno, strerror(errno));
Ken Paysonbc544be2016-10-06 19:23:47 -070053 return GRPC_OS_ERROR(errno, "pipe");
Craig Tiller9474c4a2016-02-25 07:02:39 -080054 }
Craig Tiller4f1d0f32016-05-06 17:12:37 -070055 grpc_error* err;
56 err = grpc_set_socket_nonblocking(pipefd[0], 1);
57 if (err != GRPC_ERROR_NONE) return err;
58 err = grpc_set_socket_nonblocking(pipefd[1], 1);
59 if (err != GRPC_ERROR_NONE) return err;
David Klempner78dc6cd2015-01-26 15:02:51 -080060 fd_info->read_fd = pipefd[0];
61 fd_info->write_fd = pipefd[1];
Craig Tiller4f1d0f32016-05-06 17:12:37 -070062 return GRPC_ERROR_NONE;
David Klempner78dc6cd2015-01-26 15:02:51 -080063}
64
Craig Tiller4f1d0f32016-05-06 17:12:37 -070065static grpc_error* pipe_consume(grpc_wakeup_fd* fd_info) {
David Klempner78dc6cd2015-01-26 15:02:51 -080066 char buf[128];
Craig Tillerf96dfc32015-09-10 14:43:18 -070067 ssize_t r;
David Klempner78dc6cd2015-01-26 15:02:51 -080068
Craig Tillera82950e2015-09-22 12:33:20 -070069 for (;;) {
70 r = read(fd_info->read_fd, buf, sizeof(buf));
71 if (r > 0) continue;
Craig Tiller4f1d0f32016-05-06 17:12:37 -070072 if (r == 0) return GRPC_ERROR_NONE;
Craig Tillera82950e2015-09-22 12:33:20 -070073 switch (errno) {
74 case EAGAIN:
Craig Tiller4f1d0f32016-05-06 17:12:37 -070075 return GRPC_ERROR_NONE;
Craig Tillera82950e2015-09-22 12:33:20 -070076 case EINTR:
77 continue;
78 default:
Craig Tiller4f1d0f32016-05-06 17:12:37 -070079 return GRPC_OS_ERROR(errno, "read");
David Klempner78dc6cd2015-01-26 15:02:51 -080080 }
Craig Tillera82950e2015-09-22 12:33:20 -070081 }
David Klempner78dc6cd2015-01-26 15:02:51 -080082}
83
Craig Tiller4f1d0f32016-05-06 17:12:37 -070084static grpc_error* pipe_wakeup(grpc_wakeup_fd* fd_info) {
David Klempner78dc6cd2015-01-26 15:02:51 -080085 char c = 0;
Craig Tillera82950e2015-09-22 12:33:20 -070086 while (write(fd_info->write_fd, &c, 1) != 1 && errno == EINTR)
David Klempner78dc6cd2015-01-26 15:02:51 -080087 ;
Craig Tiller4f1d0f32016-05-06 17:12:37 -070088 return GRPC_ERROR_NONE;
David Klempner78dc6cd2015-01-26 15:02:51 -080089}
90
Craig Tillera82950e2015-09-22 12:33:20 -070091static void pipe_destroy(grpc_wakeup_fd* fd_info) {
92 if (fd_info->read_fd != 0) close(fd_info->read_fd);
93 if (fd_info->write_fd != 0) close(fd_info->write_fd);
David Klempner78dc6cd2015-01-26 15:02:51 -080094}
95
Craig Tillera82950e2015-09-22 12:33:20 -070096static int pipe_check_availability(void) {
Ken Payson31caabd2016-08-06 21:27:29 -070097 grpc_wakeup_fd fd;
Sree Kuchibhotla8d5807c2016-10-26 12:55:28 -070098 fd.read_fd = fd.write_fd = -1;
99
Ken Payson31caabd2016-08-06 21:27:29 -0700100 if (pipe_init(&fd) == GRPC_ERROR_NONE) {
101 pipe_destroy(&fd);
102 return 1;
103 } else {
104 return 0;
105 }
David Klempner78dc6cd2015-01-26 15:02:51 -0800106}
107
Craig Tillere1a03a62015-02-02 07:46:55 -0800108const grpc_wakeup_fd_vtable grpc_pipe_wakeup_fd_vtable = {
Craig Tillera82950e2015-09-22 12:33:20 -0700109 pipe_init, pipe_consume, pipe_wakeup, pipe_destroy,
110 pipe_check_availability};
David Klempner78dc6cd2015-01-26 15:02:51 -0800111
Craig Tillerd6c98df2015-08-18 09:33:44 -0700112#endif /* GPR_POSIX_WAKUP_FD */