1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
5 * Copyright (C) 2001-2010, Eduardo Silva P. <edsiper@gmail.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <sys/epoll.h>
38 #include "scheduler.h"
42 mk_epoll_handlers
*mk_epoll_set_handlers(void (*read
) (int),
46 void (*timeout
) (int))
48 mk_epoll_handlers
*handler
;
50 handler
= malloc(sizeof(mk_epoll_handlers
));
51 handler
->read
= (void *) read
;
52 handler
->write
= (void *) write
;
53 handler
->error
= (void *) error
;
54 handler
->close
= (void *) close
;
55 handler
->timeout
= (void *) timeout
;
60 int mk_epoll_create(int max_events
)
64 efd
= epoll_create(max_events
);
66 perror("epoll_create");
72 void *mk_epoll_init(int efd
, mk_epoll_handlers
* handler
, int max_events
)
78 struct epoll_event
*events
;
79 struct sched_list_node
*sched
;
82 sched
= mk_sched_get_thread_conf();
84 pthread_mutex_lock(&mutex_wait_register
);
85 pthread_mutex_unlock(&mutex_wait_register
);
87 fds_timeout
= log_current_utime
+ config
->timeout
;
88 events
= mk_mem_malloc_z(max_events
*sizeof(struct epoll_event
));
92 num_fds
= epoll_wait(efd
, events
, max_events
, MK_EPOLL_WAIT_TIMEOUT
);
94 for (i
= 0; i
< num_fds
; i
++) {
95 fd
= events
[i
].data
.fd
;
97 if (events
[i
].events
& EPOLLIN
) {
99 MK_TRACE("[FD %i] EPoll Event READ", fd
);
101 ret
= (*handler
->read
) (fd
);
103 else if (events
[i
].events
& EPOLLOUT
) {
105 MK_TRACE("[FD %i] EPoll Event WRITE", fd
);
107 ret
= (*handler
->write
) (fd
);
110 else if (events
[i
].events
& (EPOLLHUP
| EPOLLERR
| EPOLLRDHUP
)) {
112 MK_TRACE("[FD %i] EPoll Event EPOLLHUP/EPOLLER", fd
);
114 ret
= (*handler
->error
) (fd
);
119 MK_TRACE("[FD %i] Epoll Event FORCE CLOSE | ret = %i", fd
, ret
);
121 (*handler
->close
) (fd
);
125 /* Check timeouts and update next one */
126 if (log_current_utime
>= fds_timeout
) {
127 mk_sched_check_timeouts(sched
);
128 fds_timeout
= log_current_utime
+ config
->timeout
;
133 int mk_epoll_add(int efd
, int fd
, int init_mode
, int behavior
)
136 struct epoll_event event
;
139 event
.events
= EPOLLERR
| EPOLLHUP
| EPOLLRDHUP
;
141 if (behavior
== MK_EPOLL_BEHAVIOR_TRIGGERED
) {
142 event
.events
|= EPOLLET
;
147 event
.events
|= EPOLLIN
;
150 event
.events
|= EPOLLOUT
;
153 event
.events
|= EPOLLIN
| EPOLLOUT
;
157 ret
= epoll_ctl(efd
, EPOLL_CTL_ADD
, fd
, &event
);
164 int mk_epoll_del(int efd
, int fd
)
168 ret
= epoll_ctl(efd
, EPOLL_CTL_DEL
, fd
, NULL
);
171 MK_TRACE("Epoll, removing fd %i from efd %i", fd
, efd
);
175 perror("\nepoll_ctl");
180 int mk_epoll_change_mode(int efd
, int fd
, int mode
)
183 struct epoll_event event
;
185 event
.events
= EPOLLET
| EPOLLERR
| EPOLLHUP
;
191 MK_TRACE("[FD %i] EPoll changing mode to READ", fd
);
193 event
.events
|= EPOLLIN
;
197 MK_TRACE("[FD %i] EPoll changing mode to WRITE", fd
);
199 event
.events
|= EPOLLOUT
;
203 MK_TRACE("[FD %i] Epoll changing mode to READ/WRITE", fd
);
205 event
.events
|= EPOLLIN
| EPOLLOUT
;
209 ret
= epoll_ctl(efd
, EPOLL_CTL_MOD
, fd
, &event
);
211 perror("\nepoll_ctl");