Move hash table to common/ directory
[lttng-tools.git] / lttng-sessiond / compat / compat-epoll.c
CommitLineData
5eb91c98
DG
1/*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; only version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18#include <fcntl.h>
19#include <limits.h>
20#include <stdlib.h>
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <unistd.h>
3bd1e081 24#include <config.h>
5eb91c98
DG
25
26#include <lttngerr.h>
27
28#include "poll.h"
29
30unsigned int poll_max_size;
31
32/*
33 * Create epoll set and allocate returned events structure.
34 */
35int compat_epoll_create(struct lttng_poll_event *events, int size, int flags)
36{
37 int ret;
38
39 if (events == NULL || size <= 0) {
40 goto error;
41 }
42
43 /* Don't bust the limit here */
44 if (size > poll_max_size) {
45 size = poll_max_size;
46 }
47
48 ret = epoll_create1(flags);
49 if (ret < 0) {
50 /* At this point, every error is fatal */
51 perror("epoll_create1");
52 goto error;
53 }
54
55 events->epfd = ret;
56
57 /* This *must* be freed by using lttng_poll_free() */
58 events->events = zmalloc(size * sizeof(struct epoll_event));
59 if (events->events == NULL) {
ba7f0ae5 60 perror("zmalloc epoll set");
5eb91c98
DG
61 goto error_close;
62 }
63
64 events->events_size = size;
65 events->nb_fd = 0;
66
67 return 0;
68
69error_close:
70 close(events->epfd);
71error:
72 return -1;
73}
74
75/*
76 * Add a fd to the epoll set with requesting events.
77 */
78int compat_epoll_add(struct lttng_poll_event *events, int fd, uint32_t req_events)
79{
80 int ret, new_size;
81 struct epoll_event ev, *ptr;
82
83 if (events == NULL || events->events == NULL || fd < 0) {
84 ERR("Bad compat epoll add arguments");
85 goto error;
86 }
87
88 ev.events = req_events;
89 ev.data.fd = fd;
90
91 ret = epoll_ctl(events->epfd, EPOLL_CTL_ADD, fd, &ev);
92 if (ret < 0) {
93 switch (errno) {
94 case EEXIST:
95 case ENOSPC:
96 case EPERM:
97 /* Print perror and goto end not failing. Show must go on. */
98 perror("epoll_ctl ADD");
99 goto end;
100 default:
101 perror("epoll_ctl ADD fatal");
102 goto error;
103 }
104 }
105
106 events->nb_fd++;
107
108 if (events->nb_fd >= events->events_size) {
109 new_size = 2 * events->events_size;
110 ptr = realloc(events->events, new_size * sizeof(struct epoll_event));
111 if (ptr == NULL) {
112 perror("realloc epoll add");
113 goto error;
114 }
115 events->events = ptr;
116 events->events_size = new_size;
117 }
118
119end:
120 return 0;
121
122error:
123 return -1;
124}
125
126/*
127 * Remove a fd from the epoll set.
128 */
129int compat_epoll_del(struct lttng_poll_event *events, int fd)
130{
131 int ret;
132
133 if (events == NULL || fd < 0) {
134 goto error;
135 }
136
137 ret = epoll_ctl(events->epfd, EPOLL_CTL_DEL, fd, NULL);
138 if (ret < 0) {
139 switch (errno) {
140 case ENOENT:
141 case EPERM:
142 /* Print perror and goto end not failing. Show must go on. */
143 perror("epoll_ctl DEL");
144 goto end;
145 default:
146 perror("epoll_ctl DEL fatal");
147 goto error;
148 }
149 perror("epoll_ctl del");
150 goto error;
151 }
152
153 events->nb_fd--;
154
155end:
156 return 0;
157
158error:
159 return -1;
160}
161
162/*
163 * Wait on epoll set. This is a blocking call of timeout value.
164 */
165int compat_epoll_wait(struct lttng_poll_event *events, int timeout)
166{
167 int ret;
168
169 if (events == NULL || events->events == NULL ||
170 events->events_size < events->nb_fd) {
171 ERR("Wrong arguments in compat_epoll_wait");
172 goto error;
173 }
174
3ada8405
DG
175 do {
176 ret = epoll_wait(events->epfd, events->events, events->nb_fd, timeout);
177 } while (ret == -1 && errno == EINTR);
5eb91c98
DG
178 if (ret < 0) {
179 /* At this point, every error is fatal */
180 perror("epoll_wait");
181 goto error;
182 }
183
184 return ret;
185
186error:
187 return -1;
188}
189
190/*
191 * Setup poll set maximum size.
192 */
193void compat_epoll_set_max_size(void)
194{
195 int ret, fd;
196 char buf[64];
197
198 poll_max_size = LTTNG_POLL_DEFAULT_SIZE;
199
200 fd = open(LTTNG_EPOLL_PROC_PATH, O_RDONLY);
201 if (fd < 0) {
202 return;
203 }
204
205 ret = read(fd, buf, sizeof(buf));
206 if (ret < 0) {
207 perror("read set max size");
208 goto error;
209 }
210
211 poll_max_size = atoi(buf);
212 if (poll_max_size <= 0) {
213 /* Extra precaution */
214 poll_max_size = LTTNG_POLL_DEFAULT_SIZE;
215 }
216
217 DBG("epoll set max size is %d", poll_max_size);
218
219error:
220 close(fd);
221}
This page took 0.031221 seconds and 4 git commands to generate.