/******************************************************************************* * 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 * *******************************************************************************/ #include #include #include #include #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); }