~greghaynes/slimhttpd/Damana

« back to all changes in this revision

Viewing changes to bin/httpd/fdevents.c

  • Committer: Gregory Haynes
  • Date: 2008-01-15 07:56:28 UTC
  • Revision ID: greg@greghaynes.net-20080115075628-u4u6mxd4kzyw05f8
Event system added

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "fdevents.h"
 
2
 
 
3
int fdevents_init(fdevents *ev, unsigned int max_events) {
 
4
 
 
5
        ev->max_events = max_events;
 
6
        ev->event_count = 0;
 
7
        
 
8
#ifdef HAVE_SYS_EVENT_H
 
9
        if (-1 == (ev->fd = kqueue())) {
 
10
                perror("initializing poll queue");
 
11
                return -1;
 
12
        }
 
13
        
 
14
        ev->events = malloc(sizeof(struct kevent) * max_events);
 
15
        ev->change_count = 0;
 
16
#elif HAVE_SYS_EPOLL_H
 
17
        if (-1 == (ev->fd = epoll_create(max_events))) {
 
18
                perror("initializing poll queue");
 
19
                return -1;
 
20
        }
 
21
        
 
22
        if (-1 == (ev->inotify_fd = inotify_init())) {
 
23
                perror("initializing inotify");
 
24
                //return -1;
 
25
        }
 
26
        
 
27
        ev->events = malloc(sizeof(struct epoll_event) * max_events);
 
28
#endif
 
29
        
 
30
        ev->job_list = malloc(sizeof(fdevent) * max_events);
 
31
        
 
32
        return 0;
 
33
}
 
34
 
 
35
void fdevents_free(fdevents *ev) {
 
36
        close(ev->fd);
 
37
#ifdef HAVE_SYS_EPOLL_H
 
38
        close(ev->inotify_fd);
 
39
#endif
 
40
        free(ev->events);
 
41
        free(ev->job_list);
 
42
}
 
43
 
 
44
int fdevents_poll(fdevents *ev, unsigned int timeout) {
 
45
        int i;
 
46
        struct timespec ts;
 
47
        
 
48
        ts.tv_sec = timeout / 1000;
 
49
        ts.tv_nsec = (timeout % 1000) * 1000000;
 
50
        
 
51
#ifdef HAVE_SYS_EVENT_H
 
52
        if (-1 == (ev->event_count = kevent(ev->fd, ev->events, ev->change_count, ev->events, ev->max_events, &ts)) && errno != EINTR)
 
53
                perror("kevent");
 
54
        
 
55
        ev->change_count = 0;
 
56
        
 
57
        //Populate the joblist
 
58
        for (i = 0;i < ev->event_count;i++) {
 
59
                ev->job_list[i].conn = ev->events[i].udata;
 
60
                ev->job_list[i].fd = ev->events[i].ident;
 
61
                
 
62
                switch (ev->events[i].filter) {
 
63
                        case EVFILT_READ: ev->job_list[i].filter = FILTER_READ; break;
 
64
                        case EVFILT_WRITE: ev->job_list[i].filter = FILTER_WRITE; break;
 
65
                        case EVFILT_VNODE: ev->job_list[i].filter = FILTER_CHANGE; break;
 
66
                        default: ev->job_list[i].filter = FILTER_ERROR;
 
67
                }
 
68
        }
 
69
#elif HAVE_SYS_EPOLL_H
 
70
        if (-1 == (ev->event_count = epoll_wait(ev->fd, ev->events, ev->max_events, timeout)) && !(errno & EINTR))
 
71
                perror("epoll");
 
72
        
 
73
        //Populate the joblist
 
74
        for (i = 0;i < ev->event_count;i++) {
 
75
                
 
76
                ev->job_list[i].conn = ev->events[i].data.ptr;
 
77
                
 
78
                switch (ev->events[i].events) {
 
79
                        case EPOLLIN: ev->job_list[i].filter = FILTER_READ; break;
 
80
                        case EPOLLOUT: ev->job_list[i].filter = FILTER_WRITE; break;
 
81
                        default: ev->job_list[i].filter = FILTER_ERROR;
 
82
                }
 
83
        }
 
84
#endif
 
85
 
 
86
        return ev->event_count;
 
87
}
 
88
 
 
89
int fdevents_add_fd(fdevents *ev, int fd, filter_t filter, void *ptr) {
 
90
        int evfilt, fflags = 0;
 
91
        
 
92
#ifdef HAVE_SYS_EVENT_H
 
93
        if (filter == FILTER_READ)
 
94
                evfilt = EVFILT_READ;
 
95
        else if (filter == FILTER_WRITE)
 
96
                evfilt = EVFILT_WRITE;
 
97
        else if (filter == FILTER_CHANGE) {
 
98
                evfilt = EVFILT_VNODE;
 
99
                fflags = NOTE_DELETE | NOTE_WRITE | NOTE_RENAME;
 
100
        }
 
101
        
 
102
        EV_SET(&ev->events[ev->change_count], fd, evfilt, EV_ADD, fflags, 0, ptr);
 
103
        ev->change_count++;
 
104
#elif HAVE_SYS_EPOLL_H
 
105
        if (filter == FILTER_READ)
 
106
                evfilt = EPOLLIN;
 
107
        else if (filter == FILTER_WRITE)
 
108
                evfilt = EPOLLOUT;
 
109
        else if (filter == FILTER_CHANGE)
 
110
                evfilt = EPOLLIN;
 
111
        
 
112
        ev->events[0].events = evfilt;
 
113
        ev->events[0].data.ptr = ptr;
 
114
        
 
115
        if (filter == FILTER_READ)
 
116
                return epoll_ctl(ev->fd, EPOLL_CTL_ADD, fd, &ev->events[0]);
 
117
        else if (filter == FILTER_WRITE)
 
118
                return epoll_ctl(ev->fd, EPOLL_CTL_MOD, fd, &ev->events[0]);
 
119
        
 
120
#endif
 
121
        return 0;
 
122
}
 
123
 
 
124
#ifdef TEST
 
125
 
 
126
#define FD_COUNT 200
 
127
 
 
128
int main() {
 
129
        fdevents ev;
 
130
        int *fd, i, count;
 
131
        
 
132
        fdevents_init(&ev, 10);
 
133
        
 
134
        fd = malloc(sizeof(int) * FD_COUNT);
 
135
        
 
136
        for (i = 0; i < FD_COUNT;i++) {
 
137
                if (-1 == (fd[i] = open("base.h", O_RDONLY))) {
 
138
                        fdevents_free(&ev);
 
139
                        perror("opening");
 
140
                        return 0;
 
141
                }
 
142
                
 
143
                fdevents_add_fd(&ev, fd[i], FILTER_READ, NULL);
 
144
        }
 
145
        
 
146
        
 
147
        if (-1 == (fdevents_poll(&ev, 5000)))
 
148
                perror("polling");
 
149
        
 
150
        if (ev.event_count > 0)
 
151
                printf("events happened!");
 
152
        
 
153
        for (i = 0; i < FD_COUNT;i++) {
 
154
                if (-1 == (close(fd[i]))) {
 
155
                        fdevents_free(&ev);
 
156
                        perror("closing");
 
157
                        return 0;
 
158
                }
 
159
        }
 
160
        
 
161
        free(fd);
 
162
        fdevents_free(&ev);
 
163
        
 
164
        return 0;
 
165
}
 
166
#endif