Asterisk - The Open Source Telephony Project GIT-master-a358458
alertpipe.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2017, Sean Bright
5 *
6 * Sean Bright <sean.bright@gmail.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \brief Alert Pipe API
22 *
23 * \author Sean Bright
24 */
25
26#include "asterisk.h"
27
28#include <unistd.h>
29#include <fcntl.h>
30
31#ifdef HAVE_EVENTFD
32# include <sys/eventfd.h>
33#endif
34
35#include "asterisk/alertpipe.h"
36#include "asterisk/logger.h"
37
39{
40#ifdef HAVE_EVENTFD
41
42 int fd = eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE);
43 if (fd > -1) {
44 alert_pipe[0] = alert_pipe[1] = fd;
45 return 0;
46 }
47
48 ast_log(LOG_WARNING, "Failed to create alert pipe with eventfd(), falling back to pipe(): %s\n",
49 strerror(errno));
51
52#endif
53
54#ifdef HAVE_PIPE2
55
56 if (pipe2(alert_pipe, O_NONBLOCK)) {
57 ast_log(LOG_WARNING, "Failed to create alert pipe: %s\n", strerror(errno));
58 return -1;
59 }
60
61#else
62
63 if (pipe(alert_pipe)) {
64 ast_log(LOG_WARNING, "Failed to create alert pipe: %s\n", strerror(errno));
65 return -1;
66 } else {
67 if (ast_fd_set_flags(alert_pipe[0], O_NONBLOCK)
68 || ast_fd_set_flags(alert_pipe[1], O_NONBLOCK)) {
70 return -1;
71 }
72 }
73
74#endif
75
76 return 0;
77}
78
80{
81#ifdef HAVE_EVENTFD
82
83 if (alert_pipe[0] == alert_pipe[1]) {
84 if (alert_pipe[0] > -1) {
85 close(alert_pipe[0]);
87 }
88 return;
89 }
90
91#endif
92
93 if (alert_pipe[0] > -1) {
94 close(alert_pipe[0]);
95 }
96 if (alert_pipe[1] > -1) {
97 close(alert_pipe[1]);
98 }
100}
101
103{
104 uint64_t tmp;
105
108 }
109
110 if (read(alert_pipe[0], &tmp, sizeof(tmp)) < 0) {
111 if (errno != EINTR && errno != EAGAIN) {
112 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
113 return AST_ALERT_READ_FAIL;
114 }
115 }
116
118}
119
121{
122 uint64_t tmp = 1;
123
125 errno = EBADF;
126 return 0;
127 }
128
129 /* preset errno in case returned size does not match */
130 errno = EPIPE;
131 return write(alert_pipe[1], &tmp, sizeof(tmp)) != sizeof(tmp);
132}
133
135{
136 int bytes_read;
137 uint64_t tmp[16];
138
141 }
142
143 /* Read the alertpipe until it is exhausted. */
144 for (;;) {
145 bytes_read = read(alert_pipe[0], tmp, sizeof(tmp));
146 if (bytes_read < 0) {
147 if (errno == EINTR) {
148 continue;
149 }
150 if (errno == EAGAIN || errno == EWOULDBLOCK) {
151 /*
152 * Would block so nothing left to read.
153 * This is the normal loop exit.
154 */
155 break;
156 }
157 ast_log(LOG_WARNING, "read() failed flushing alertpipe: %s\n",
158 strerror(errno));
159 return AST_ALERT_READ_FAIL;
160 }
161 if (!bytes_read) {
162 /* Read nothing so we are done */
163 break;
164 }
165 }
166
168}
void ast_alertpipe_close(int alert_pipe[2])
Close an alert pipe.
Definition: alertpipe.c:79
ssize_t ast_alertpipe_write(int alert_pipe[2])
Write an event to an alert pipe.
Definition: alertpipe.c:120
ast_alert_status_t ast_alertpipe_flush(int alert_pipe[2])
Consume all alerts written to the alert pipe.
Definition: alertpipe.c:134
int ast_alertpipe_init(int alert_pipe[2])
Initialize an alert pipe.
Definition: alertpipe.c:38
ast_alert_status_t ast_alertpipe_read(int alert_pipe[2])
Read an event from an alert pipe.
Definition: alertpipe.c:102
void ast_alertpipe_clear(int alert_pipe[2])
Sets the alert pipe file descriptors to default values.
Definition: alertpipe.h:98
int ast_alertpipe_readable(int alert_pipe[2])
Determine if the alert pipe is readable.
Definition: alertpipe.h:114
ast_alert_status_t
Definition: alertpipe.h:24
@ AST_ALERT_READ_FAIL
Definition: alertpipe.h:27
@ AST_ALERT_READ_SUCCESS
Definition: alertpipe.h:25
@ AST_ALERT_NOT_READABLE
Definition: alertpipe.h:26
int ast_alertpipe_writable(int alert_pipe[2])
Determine if the alert pipe is writable.
Definition: alertpipe.h:130
Asterisk main include file. File version handling, generic pbx functions.
#define ast_log
Definition: astobj2.c:42
static int tmp()
Definition: bt_open.c:389
Support for logging to various files, console and syslog Configuration in file logger....
#define LOG_WARNING
int errno
int alert_pipe[2]
Definition: res_corosync.c:276
#define ast_fd_set_flags(fd, flags)
Set flags on the given file descriptor.
Definition: utils.h:1039