diff options
author | Daniel Lezcano <daniel.lezcano@linaro.org> | 2011-06-21 00:57:08 +0200 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2011-06-21 00:57:08 +0200 |
commit | 8be52603048f381e7570984593e8d2d17d79f8b9 (patch) | |
tree | 2e6a29570da321cef3ab4026597bbc92abdf58ad | |
parent | 28203df25a194728c8cab42a3035acf04c3db492 (diff) |
add a real mainloop
Add a mainloop code with registering of the callbacks and co.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | mainloop.c | 122 | ||||
-rw-r--r-- | mainloop.h | 22 |
3 files changed, 146 insertions, 1 deletions
@@ -4,7 +4,8 @@ MANDIR=/usr/share/man/man8 CFLAGS?=-O1 -g -Wall -Wshadow CC?=gcc -OBJS = powerdebug.o sensor.o clocks.o regulator.o display.o tree.o utils.o +OBJS = powerdebug.o sensor.o clocks.o regulator.o \ + display.o tree.o utils.o mainloop.o default: powerdebug diff --git a/mainloop.c b/mainloop.c new file mode 100644 index 0000000..d63d703 --- /dev/null +++ b/mainloop.c @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (C) 2010, Linaro Limited. + * + * This file is part of PowerDebug. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Author: + * Daniel Lezcano <daniel.lezcano@linaro.org> + * + *******************************************************************************/ + +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> +#include <sys/epoll.h> +#include "mainloop.h" + +static int epfd = -1; +static unsigned short nrhandler; + +struct mainloop_data { + mainloop_callback_t cb; + void *data; + int fd; +}; + +struct mainloop_data **mds; + +#define MAX_EVENTS 10 + +int _mainloop(unsigned int timeout) +{ + int i, nfds; + struct epoll_event events[MAX_EVENTS]; + struct mainloop_data *md; + + if (epfd < 0) + return -1; + + for (;;) { + + nfds = epoll_wait(epfd, events, MAX_EVENTS, timeout); + if (nfds < 0) { + if (errno == EINTR) + continue; + return -1; + } + + for (i = 0; i < nfds; i++) { + md = events[i].data.ptr; + + if (md->cb(md->fd, md->data) > 0) + return 0; + } + + } +} + +int mainloop_add(int fd, mainloop_callback_t cb, void *data) +{ + struct epoll_event ev = { + .events = EPOLLIN, + }; + + struct mainloop_data *md; + + if (fd >= nrhandler) { + mds = realloc(mds, sizeof(*mds) * (fd + 1)); + if (!mds) + return -1; + nrhandler = fd + 1; + } + + md = malloc(sizeof(*md)); + if (!md) + return -1; + + md->data = data; + md->cb = cb; + md->fd = fd; + + mds[fd] = md; + ev.data.ptr = md; + + if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) < 0) { + free(md); + return -1; + } + + return 0; +} + +int mainloop_del(int fd) +{ + if (fd >= nrhandler) + return -1; + + if (epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL) < 0) + return -1; + + free(mds[fd]); + + return 0; +} + +int mainloop_init(void) +{ + epfd = epoll_create(2); + if (epfd < 0) + return -1; + + return 0; +} + +void mainloop_fini(void) +{ + close(epfd); +} diff --git a/mainloop.h b/mainloop.h new file mode 100644 index 0000000..3b4c253 --- /dev/null +++ b/mainloop.h @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (C) 2010, Linaro Limited. + * + * This file is part of PowerDebug. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Author: + * Daniel Lezcano <daniel.lezcano@linaro.org> + * + *******************************************************************************/ + +typedef int (*mainloop_callback_t)(int fd, void *data); + +extern int _mainloop(unsigned int timeout); +extern int mainloop_add(int fd, mainloop_callback_t cb, void *data); +extern int mainloop_del(int fd); +extern int mainloop_init(void); +extern void mainloop_fini(void); |