Fix UST renaming and update ust headers
[lttng-tools.git] / ltt-sessiond / compat / compat-epoll.c
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>
24 #include <config.h>
25
26 #include <lttngerr.h>
27
28 #include "poll.h"
29
30 unsigned int poll_max_size;
31
32 /*
33 * Create epoll set and allocate returned events structure.
34 */
35 int 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) {
60 perror("malloc epoll set");
61 goto error_close;
62 }
63
64 events->events_size = size;
65 events->nb_fd = 0;
66
67 return 0;
68
69 error_close:
70 close(events->epfd);
71 error:
72 return -1;
73 }
74
75 /*
76 * Add a fd to the epoll set with requesting events.
77 */
78 int 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
119 end:
120 return 0;
121
122 error:
123 return -1;
124 }
125
126 /*
127 * Remove a fd from the epoll set.
128 */
129 int 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
155 end:
156 return 0;
157
158 error:
159 return -1;
160 }
161
162 /*
163 * Wait on epoll set. This is a blocking call of timeout value.
164 */
165 int 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
175 do {
176 ret = epoll_wait(events->epfd, events->events, events->nb_fd, timeout);
177 } while (ret == -1 && errno == EINTR);
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
186 error:
187 return -1;
188 }
189
190 /*
191 * Setup poll set maximum size.
192 */
193 void 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
219 error:
220 close(fd);
221 }
This page took 0.033964 seconds and 5 git commands to generate.