blob: 02dda98ce0370952645c5821c0bc1a01d88bcb2d [file] [log] [blame]
Daniel Lezcano8be52602011-06-21 00:57:08 +02001/*******************************************************************************
2 * Copyright (C) 2010, Linaro Limited.
3 *
4 * This file is part of PowerDebug.
5 *
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *
11 * Author:
12 * Daniel Lezcano <daniel.lezcano@linaro.org>
13 *
14 *******************************************************************************/
15
16#include <stdlib.h>
17#include <errno.h>
18#include <unistd.h>
19#include <sys/epoll.h>
20#include "mainloop.h"
21
22static int epfd = -1;
23static unsigned short nrhandler;
24
25struct mainloop_data {
26 mainloop_callback_t cb;
27 void *data;
28 int fd;
29};
30
31struct mainloop_data **mds;
32
33#define MAX_EVENTS 10
34
Daniel Lezcanodb145802011-06-21 00:57:08 +020035int mainloop(unsigned int timeout)
Daniel Lezcano8be52602011-06-21 00:57:08 +020036{
37 int i, nfds;
38 struct epoll_event events[MAX_EVENTS];
39 struct mainloop_data *md;
40
41 if (epfd < 0)
42 return -1;
43
44 for (;;) {
45
46 nfds = epoll_wait(epfd, events, MAX_EVENTS, timeout);
47 if (nfds < 0) {
48 if (errno == EINTR)
49 continue;
50 return -1;
51 }
52
53 for (i = 0; i < nfds; i++) {
54 md = events[i].data.ptr;
55
56 if (md->cb(md->fd, md->data) > 0)
57 return 0;
58 }
59
60 }
61}
62
63int mainloop_add(int fd, mainloop_callback_t cb, void *data)
64{
65 struct epoll_event ev = {
66 .events = EPOLLIN,
67 };
68
69 struct mainloop_data *md;
70
71 if (fd >= nrhandler) {
72 mds = realloc(mds, sizeof(*mds) * (fd + 1));
73 if (!mds)
74 return -1;
75 nrhandler = fd + 1;
76 }
77
78 md = malloc(sizeof(*md));
79 if (!md)
80 return -1;
81
82 md->data = data;
83 md->cb = cb;
84 md->fd = fd;
85
86 mds[fd] = md;
87 ev.data.ptr = md;
88
89 if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) < 0) {
90 free(md);
91 return -1;
92 }
93
94 return 0;
95}
96
97int mainloop_del(int fd)
98{
99 if (fd >= nrhandler)
100 return -1;
101
102 if (epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL) < 0)
103 return -1;
104
105 free(mds[fd]);
106
107 return 0;
108}
109
110int mainloop_init(void)
111{
112 epfd = epoll_create(2);
113 if (epfd < 0)
114 return -1;
115
116 return 0;
117}
118
119void mainloop_fini(void)
120{
121 close(epfd);
122}