1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
5 * Copyright (C) 2008, Eduardo Silva P.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <sys/epoll.h>
38 #include "scheduler.h"
41 #define MAX_EVENTS 5000
43 mk_epoll_handlers
*mk_epoll_set_handlers(void (*read
)(void *),
44 void (*write
)(void *),
45 void (*error
)(void *),
46 void (*close
)(void *),
47 void (*timeout
)(void *))
49 mk_epoll_handlers
*handler
;
51 handler
= malloc(sizeof(mk_epoll_handlers
));
52 handler
->read
= (void *) read
;
53 handler
->write
= (void *) write
;
54 handler
->error
= (void *) error
;
55 handler
->close
= (void *) close
;
56 handler
->timeout
= (void *) timeout
;
61 int mk_epoll_create(int max_events
)
65 efd
= epoll_create(max_events
);
67 perror("epoll_create");
73 void *mk_epoll_init(int efd
, mk_epoll_handlers
*handler
, int max_events
)
78 struct epoll_event events
[max_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
;
90 num_fds
= epoll_wait(efd
, events
,
91 max_events
, MK_EPOLL_WAIT_TIMEOUT
);
93 for(i
=0; i
<num_fds
; i
++) {
94 fd
= events
[i
].data
.fd
;
95 // Case 1: Error condition
96 if (events
[i
].events
& (EPOLLHUP
| EPOLLERR
)) {
97 (* handler
->error
)((void *)fd
);
101 if(events
[i
].events
& EPOLLIN
)
103 ret
= (* handler
->read
)((void *) fd
);
105 else if(events
[i
].events
& EPOLLOUT
)
107 ret
= (* handler
->write
)((void *) fd
);
112 (* handler
->close
)((void *) fd
);
116 /* Check timeouts and update next one */
117 if(log_current_utime
>= fds_timeout
){
118 mk_sched_check_timeouts(&sched
);
119 fds_timeout
= log_current_utime
+ config
->timeout
;
124 int mk_epoll_add_client(int efd
, int socket
, int mode
)
127 struct epoll_event event
;
130 event
.events
= EPOLLIN
| EPOLLERR
| EPOLLHUP
;
131 event
.data
.fd
= socket
;
133 if(mode
== MK_EPOLL_BEHAVIOR_TRIGGERED
)
135 event
.events
|= EPOLLET
;
139 ret
= epoll_ctl(efd
, EPOLL_CTL_ADD
, socket
, &event
);
147 int mk_epoll_socket_change_mode(int efd
, int socket
, int mode
)
150 struct epoll_event event
;
152 event
.events
= EPOLLET
| EPOLLERR
| EPOLLHUP
;
153 event
.data
.fd
= socket
;
158 event
.events
|= EPOLLIN
;
161 event
.events
|= EPOLLOUT
;
164 event
.events
|= EPOLLIN
| EPOLLOUT
;
168 ret
= epoll_ctl(efd
, EPOLL_CTL_MOD
, socket
, &event
);
171 perror("\nepoll_ctl");