]> git.ipfire.org Git - people/ms/rstp.git/blame - epoll_loop.c
Initial commit
[people/ms/rstp.git] / epoll_loop.c
CommitLineData
ad02a0eb
SH
1/*****************************************************************************
2 Copyright (c) 2006 EMC Corporation.
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; either version 2 of the License, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Authors: Srinivas Aji <Aji_Srinivas@emc.com>
22
23******************************************************************************/
24
25#include "epoll_loop.h"
26
27#include <sys/epoll.h>
28#include <errno.h>
29#include <sys/time.h>
30#include <time.h>
31#include <stdio.h>
32#include <unistd.h>
33
34#include "bridge_ctl.h"
35
36// globals
37int epoll_fd = -1;
38struct timeval nexttimeout;
39
40int init_epoll(void)
41{
42 int r = epoll_create(128);
43 if (r < 0) {
44 fprintf(stderr, "epoll_create failed: %m\n");
45 return -1;
46 }
47 epoll_fd = r;
48 return 0;
49}
50
51int add_epoll(struct epoll_event_handler *h)
52{
53 struct epoll_event ev =
54 {
55 .events = EPOLLIN,
56 .data.ptr = h,
57 };
58 h->ref_ev = NULL;
59 int r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, h->fd, &ev);
60 if (r < 0) {
61 fprintf(stderr, "epoll_ctl_add: %m\n");
62 return -1;
63 }
64 return 0;
65}
66
67int remove_epoll(struct epoll_event_handler *h)
68{
69 int r = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, h->fd, NULL);
70 if (r < 0) {
71 fprintf(stderr, "epoll_ctl_del: %m\n");
72 return -1;
73 }
74 if (h->ref_ev && h->ref_ev->data.ptr == h) {
75 h->ref_ev->data.ptr = NULL;
76 h->ref_ev = NULL;
77 }
78 return 0;
79}
80
81void clear_epoll(void)
82{
83 if (epoll_fd >= 0)
84 close(epoll_fd);
85}
86
87int time_diff(struct timeval *second, struct timeval *first)
88{
89 return (second->tv_sec - first->tv_sec)*1000
90 + (second->tv_usec - first->tv_usec)/1000;
91}
92
93void run_timeouts(void)
94{
95 bridge_one_second();
96 nexttimeout.tv_sec++;
97}
98
99int epoll_main_loop(void)
100{
101 gettimeofday(&nexttimeout, NULL);
102 nexttimeout.tv_sec++;
103#define EV_SIZE 8
104 struct epoll_event ev[EV_SIZE];
105
106 while (1) {
107 int r, i;
108 int timeout;
109
110 struct timeval tv;
111 gettimeofday(&tv, NULL);
112 timeout = time_diff(&nexttimeout, &tv);
113 if (timeout < 0) {
114 run_timeouts();
115 timeout = 0;
116 }
117
118 r = epoll_wait(epoll_fd, ev, EV_SIZE, timeout);
119 if (r < 0 && errno != EINTR) {
120 fprintf(stderr, "epoll_wait: %m\n");
121 return -1;
122 }
123 for (i = 0; i < r; i++) {
124 struct epoll_event_handler *p = ev[i].data.ptr;
125 if (p != NULL)
126 p->ref_ev = &ev[i];
127 }
128 for (i = 0; i < r; i++) {
129 struct epoll_event_handler *p = ev[i].data.ptr;
130 if (p && p->handler)
131 p->handler(ev[i].events, p);
132 }
133 for (i = 0; i < r; i++) {
134 struct epoll_event_handler *p = ev[i].data.ptr;
135 if (p != NULL)
136 p->ref_ev = NULL;
137 }
138 }
139
140 return 0;
141}