2 * Copyright 2016 IoT.bzh
3 * Author: José Bollo <jose.bollo@iot.bzh>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 #include <sys/epoll.h>
25 #include "utils-upoll.h"
32 void (*write)(void *);
33 void (*hangup)(void *);
38 static int pollfd = 0;
39 static struct upoll *head = NULL;
40 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
42 int upoll_is_valid(struct upoll *upoll)
44 struct upoll *it = head;
53 struct upoll *upoll_open(int fd, void *closure)
59 /* opens the epoll stream */
61 pollfd = epoll_create1(EPOLL_CLOEXEC);
73 result = calloc(1, sizeof *result);
79 result->closure = closure;
80 pthread_mutex_lock(&mutex);
83 pthread_mutex_unlock(&mutex);
88 rc = epoll_ctl(pollfd, EPOLL_CTL_ADD, fd, &e);
99 static int update(struct upoll *upoll)
101 struct epoll_event e;
102 e.events = (uint32_t)((upoll->read != NULL ? EPOLLIN : 0 )
103 | (upoll->write != NULL ? EPOLLOUT : 0));
105 return epoll_ctl(pollfd, EPOLL_CTL_MOD, upoll->fd, &e);
108 int upoll_on_readable(struct upoll *upoll, void (*process)(void *))
111 assert(upoll_is_valid(upoll));
113 upoll->read = process;
114 return update(upoll);
117 int upoll_on_writable(struct upoll *upoll, void (*process)(void *))
120 assert(upoll_is_valid(upoll));
122 upoll->write = process;
123 return update(upoll);
126 void upoll_on_hangup(struct upoll *upoll, void (*process)(void *))
129 assert(upoll_is_valid(upoll));
131 upoll->hangup = process;
134 void upoll_close(struct upoll *upoll)
139 assert(upoll_is_valid(upoll));
141 epoll_ctl(pollfd, EPOLL_CTL_DEL, upoll->fd, NULL);
142 pthread_mutex_lock(&mutex);
147 pthread_mutex_unlock(&mutex);
151 void upoll_wait(int timeout)
154 struct epoll_event e;
160 rc = epoll_wait(pollfd, &e, 1, timeout);
163 if ((e.events & EPOLLIN) && upoll->read)
164 upoll->read(upoll->closure);
165 if ((e.events & EPOLLOUT) && upoll->write)
166 upoll->write(upoll->closure);
167 if ((e.events & EPOLLHUP) && upoll->hangup)
168 upoll->hangup(upoll->closure);